├── .editorconfig ├── .eslintignore ├── .eslintrc.yaml ├── .gitattributes ├── .github ├── codeql │ └── codeql-configuration.yml ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ └── main.yaml ├── .gitignore ├── .prettierignore ├── .prettierrc.yaml ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── contributes ├── grammars │ ├── wast.json │ └── wat.json └── languages │ ├── wast.json │ └── wat.json ├── package-lock.json ├── package.json ├── script └── syntax.js ├── src ├── client │ └── index.ts ├── contributes │ └── grammars │ │ ├── basis.ts │ │ ├── schema.ts │ │ ├── wast.ts │ │ └── wat.ts └── extension.ts ├── tsconfig.json └── vscode.proposed.d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | out 2 | vscode.proposed.d.ts 3 | -------------------------------------------------------------------------------- /.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | parser: "@typescript-eslint/parser" 3 | parserOptions: 4 | project: "./tsconfig.json" 5 | plugins: 6 | - "@typescript-eslint" 7 | extends: 8 | - eslint:recommended 9 | - plugin:@typescript-eslint/eslint-recommended 10 | - plugin:@typescript-eslint/recommended-requiring-type-checking 11 | - plugin:@typescript-eslint/recommended 12 | - plugin:prettier/recommended 13 | - prettier 14 | rules: 15 | "@typescript-eslint/no-inferrable-types": ["off"] 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.gif binary 3 | *.png binary 4 | *.json text eol=lf 5 | *.md text eol=lf 6 | *.ts text eol=lf 7 | .editorconfig text eol=lf 8 | .gitattributes text eol=lf 9 | .gitignore text eol=lf 10 | .vscodeignore text eol=lf 11 | LICENSE text eol=lf 12 | yarn.lock text eol=lf 13 | -------------------------------------------------------------------------------- /.github/codeql/codeql-configuration.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL Configuration" 2 | 3 | paths: 4 | - "./src" 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | analyze: 11 | name: Analyze 12 | runs-on: ubuntu-latest 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | language: ["javascript"] 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | with: 21 | fetch-depth: 2 22 | - run: git checkout HEAD^2 23 | if: ${{ github.event_name == 'pull_request' }} 24 | - name: Initialize CodeQL 25 | uses: github/codeql-action/init@v1 26 | with: 27 | languages: ${{ matrix.language }} 28 | - name: Perform CodeQL Analysis 29 | uses: github/codeql-action/analyze@v1 30 | -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: main 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | audit: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@master 10 | - uses: actions/setup-node@v1 11 | with: 12 | node-version: "13.x" 13 | - run: npm audit 14 | 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@master 19 | - uses: actions/setup-node@v1 20 | with: 21 | node-version: "13.x" 22 | - run: npm ci 23 | - run: npm run build 24 | 25 | lint: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@master 29 | - uses: actions/setup-node@v1 30 | with: 31 | node-version: "13.x" 32 | - run: npm ci 33 | - run: npm run lint 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | 3 | ### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/Node.gitignore 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # node-waf configuration 29 | .lock-wscript 30 | 31 | # Compiled binary addons (http://nodejs.org/api/addons.html) 32 | build/Release 33 | 34 | # Dependency directories 35 | node_modules 36 | jspm_packages 37 | 38 | # Optional npm cache directory 39 | .npm 40 | 41 | # Optional eslint cache 42 | .eslintcache 43 | 44 | # Optional REPL history 45 | .node_repl_history 46 | 47 | 48 | ### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/OCaml.gitignore 49 | 50 | *.annot 51 | *.cmo 52 | *.cma 53 | *.cmi 54 | *.a 55 | *.o 56 | *.cmx 57 | *.cmxs 58 | *.cmxa 59 | 60 | # ocamlbuild working directory 61 | _build/ 62 | 63 | # ocamlbuild targets 64 | *.byte 65 | *.native 66 | 67 | # oasis generated files 68 | setup.data 69 | setup.log 70 | 71 | 72 | ### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/Global/VisualStudioCode.gitignore 73 | 74 | .vscode/* 75 | !.vscode/settings.json 76 | !.vscode/tasks.json 77 | !.vscode/launch.json 78 | 79 | 80 | ### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/Global/Linux.gitignore 81 | 82 | *~ 83 | 84 | # temporary files which can be created if a process still has a handle open of a deleted file 85 | .fuse_hidden* 86 | 87 | # KDE directory preferences 88 | .directory 89 | 90 | # Linux trash folder which might appear on any partition or disk 91 | .Trash-* 92 | 93 | 94 | ### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/Global/macOS.gitignore 95 | 96 | *.DS_Store 97 | .AppleDouble 98 | .LSOverride 99 | 100 | # Icon must end with two \r 101 | Icon 102 | 103 | 104 | # Thumbnails 105 | ._* 106 | 107 | # Files that might appear in the root of a volume 108 | .DocumentRevisions-V100 109 | .fseventsd 110 | .Spotlight-V100 111 | .TemporaryItems 112 | .Trashes 113 | .VolumeIcon.icns 114 | .com.apple.timemachine.donotpresent 115 | 116 | # Directories potentially created on remote AFP share 117 | .AppleDB 118 | .AppleDesktop 119 | Network Trash Folder 120 | Temporary Items 121 | .apdisk 122 | 123 | 124 | ### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/Global/Windows.gitignore 125 | 126 | # Windows image file caches 127 | Thumbs.db 128 | ehthumbs.db 129 | 130 | # Folder config file 131 | Desktop.ini 132 | 133 | # Recycle Bin used on file shares 134 | $RECYCLE.BIN/ 135 | 136 | # Windows Installer files 137 | *.cab 138 | *.msi 139 | *.msm 140 | *.msp 141 | 142 | # Windows shortcuts 143 | *.lnk 144 | 145 | 146 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | contributes 2 | out 3 | vscode.proposed.d.ts 4 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | bracketSpacing: true 2 | printWidth: 120 3 | semi: true 4 | singleQuote: false 5 | tabWidth: 2 6 | trailingComma: all 7 | useTabs: false 8 | overrides: 9 | - files: "*.ts" 10 | options: 11 | parser: typescript 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Run Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "runtimeExecutable": "${execPath}", 9 | "args": ["--extensionDevelopmentPath=${workspaceFolder}"], 10 | "outFiles": ["${workspaceFolder}/out/**/*.js"], 11 | "preLaunchTask": "${defaultBuildTask}" 12 | }, 13 | { 14 | "name": "Extension Tests", 15 | "type": "extensionHost", 16 | "request": "launch", 17 | "runtimeExecutable": "${execPath}", 18 | "args": [ 19 | "--extensionDevelopmentPath=${workspaceFolder}", 20 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 21 | ], 22 | "outFiles": ["${workspaceFolder}/out/test/**/*.js"], 23 | "preLaunchTask": "${defaultBuildTask}" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "out": false 4 | }, 5 | "search.exclude": { 6 | "out": true 7 | }, 8 | "typescript.tsc.autoDetect": "off" 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "watch", 7 | "problemMatcher": "$tsc-watch", 8 | "isBackground": true, 9 | "presentation": { 10 | "reveal": "never" 11 | }, 12 | "group": { 13 | "kind": "build", 14 | "isDefault": true 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | This project is governed by the Contributor Covenant version 2.0 2 | (https://www.contributor-covenant.org/version/2/0/code_of_conduct). 3 | All contributors and participants agree to abide by its terms. 4 | To report violations, send an email to darinmorrison+conduct@gmail.com. 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

vscode-wasm

3 |

4 | 6 | 7 |

8 |

9 | 10 | 11 | 12 |

13 | Visual Studio Code client for the WebAssembly language server 14 |
15 | 16 | ## Status 17 | 18 | The client extension is still in an early state. It is usable but many advanced features have not yet been implemented. The syntax highlighting is also incomplete. 19 | 20 | ## Usage 21 | 22 | The client extension has not yet had a stable release. You can build and install it locally if you would like to experiment with it in the meantime. 23 | 24 | ### Installing the Client Extension 25 | 26 | First ensure that you have the [node toolchain](https://nodejs.org/en/download/) installed, then proceed as follows: 27 | 28 | ```bash 29 | git clone --recursive https://github.com/wasm-lsp/vscode-wasm 30 | cd vscode-wasm 31 | npm i -g vsce 32 | npm i 33 | vsce package 34 | ``` 35 | 36 | This will produce a `vscode-wasm-.vsix` file in the project root. 37 | 38 | Next, open Code and show the command palette (`CTRL+SHIFT+P` or `CMD+SHIFT+P`) and type `install`, then select `Extensions: Install from VSIX...` from the list. Point the file selector to the previously generated `vscode-wasm-.vsix`. Finally, hit the `reload` button when prompted. 39 | -------------------------------------------------------------------------------- /contributes/grammars/wat.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WebAssembly Module", 3 | "scopeName": "source.wasm.wat", 4 | "fileTypes": [ 5 | ".wat" 6 | ], 7 | "patterns": [ 8 | { 9 | "include": "#PARSE" 10 | } 11 | ], 12 | "repository": { 13 | "PARSE": { 14 | "name": "meta.PARSE.wasm", 15 | "patterns": [ 16 | { 17 | "include": "#extra" 18 | }, 19 | { 20 | "begin": "\\(", 21 | "beginCaptures": { 22 | "0": { 23 | "name": "meta.brace.round.wasm" 24 | } 25 | }, 26 | "end": "\\)", 27 | "endCaptures": { 28 | "0": { 29 | "name": "meta.brace.round.wasm" 30 | } 31 | }, 32 | "patterns": [ 33 | { 34 | "include": "#extra" 35 | }, 36 | { 37 | "include": "#module" 38 | }, 39 | { 40 | "include": "#moduleField" 41 | } 42 | ] 43 | } 44 | ] 45 | }, 46 | "alignValue": { 47 | "match": "[[:space:]]+(\\balign=(?:[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)\\b)", 48 | "captures": { 49 | "1": { 50 | "name": "storage.modifier.wasm" 51 | } 52 | } 53 | }, 54 | "annotation": { 55 | "name": "meta.annotation.wasm", 56 | "begin": "\\((?=@)", 57 | "beginCaptures": { 58 | "0": { 59 | "name": "meta.brace.round.annotation.wasm punctuation.definition.tag" 60 | } 61 | }, 62 | "end": "\\)", 63 | "endCaptures": { 64 | "0": { 65 | "name": "meta.brace.round.annotation.wasm punctuation.definition.tag" 66 | } 67 | }, 68 | "patterns": [ 69 | { 70 | "begin": "@", 71 | "beginCaptures": { 72 | "0": { 73 | "name": "meta.annotation.name.wasm punctuation.definition.tag" 74 | } 75 | }, 76 | "end": "(?=\\))", 77 | "endCaptures": { 78 | "0": { 79 | "name": "meta.brace.round.annotation.wasm" 80 | } 81 | }, 82 | "patterns": [ 83 | { 84 | "begin": "[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+", 85 | "beginCaptures": { 86 | "0": { 87 | "name": "meta.annotation.wasm constant.regexp" 88 | } 89 | }, 90 | "end": "(?=\\))", 91 | "contentName": "comment.wasm", 92 | "patterns": [ 93 | { 94 | "include": "#annotationPart" 95 | } 96 | ] 97 | } 98 | ] 99 | } 100 | ] 101 | }, 102 | "annotationParens": { 103 | "name": "meta.annotationParens.wasm", 104 | "begin": "\\(", 105 | "end": "\\)", 106 | "patterns": [ 107 | { 108 | "include": "#annotationPart" 109 | } 110 | ] 111 | }, 112 | "annotationPart": { 113 | "name": "meta.annotationPart.wasm", 114 | "patterns": [ 115 | { 116 | "include": "#comment" 117 | }, 118 | { 119 | "include": "#annotationParens" 120 | }, 121 | { 122 | "match": "[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 123 | }, 124 | { 125 | "begin": "\"", 126 | "end": "(\")|((?:[^\\\\\\n])$)", 127 | "patterns": [ 128 | { 129 | "name": "constant.character.escape.wasm" 130 | } 131 | ] 132 | } 133 | ] 134 | }, 135 | "blockBlock": { 136 | "name": "meta.blockBlock.wasm", 137 | "begin": "\\bblock\\b", 138 | "beginCaptures": { 139 | "0": { 140 | "name": "keyword.control.wasm" 141 | } 142 | }, 143 | "end": "\\bend\\b", 144 | "endCaptures": { 145 | "0": { 146 | "name": "keyword.control.wasm" 147 | } 148 | }, 149 | "patterns": [ 150 | { 151 | "include": "#extra" 152 | }, 153 | { 154 | "name": "variable.other.wasm", 155 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 156 | }, 157 | { 158 | "include": "#typeUse" 159 | }, 160 | { 161 | "include": "#funcTypeParams" 162 | }, 163 | { 164 | "include": "#funcTypeResults" 165 | }, 166 | { 167 | "include": "#instrList" 168 | } 169 | ] 170 | }, 171 | "blockComment": { 172 | "name": "meta.blockComment.wasm comment.block.wasm", 173 | "begin": "(\\(;)", 174 | "beginCaptures": { 175 | "1": { 176 | "name": "punctuation.definition.comment.wasm" 177 | } 178 | }, 179 | "end": "(;\\))", 180 | "endCaptures": { 181 | "1": { 182 | "name": "punctuation.definition.comment.wasm" 183 | } 184 | }, 185 | "patterns": [ 186 | { 187 | "include": "#blockComment" 188 | } 189 | ] 190 | }, 191 | "blockIf": { 192 | "name": "meta.blockIf.wasm", 193 | "begin": "\\bif\\b", 194 | "beginCaptures": { 195 | "0": { 196 | "name": "keyword.control.wasm" 197 | } 198 | }, 199 | "end": "\\bend\\b", 200 | "endCaptures": { 201 | "0": { 202 | "name": "keyword.control.wasm" 203 | } 204 | }, 205 | "patterns": [ 206 | { 207 | "include": "#extra" 208 | }, 209 | { 210 | "name": "variable.other.wasm", 211 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 212 | }, 213 | { 214 | "include": "#typeUse" 215 | }, 216 | { 217 | "include": "#funcTypeParams" 218 | }, 219 | { 220 | "include": "#funcTypeResults" 221 | }, 222 | { 223 | "include": "#instrList" 224 | } 225 | ] 226 | }, 227 | "blockLoop": { 228 | "name": "meta.blockLoop.wasm", 229 | "begin": "\\bloop\\b", 230 | "beginCaptures": { 231 | "0": { 232 | "name": "keyword.control.wasm" 233 | } 234 | }, 235 | "end": "\\bend\\b", 236 | "endCaptures": { 237 | "0": { 238 | "name": "keyword.control.wasm" 239 | } 240 | }, 241 | "patterns": [ 242 | { 243 | "include": "#extra" 244 | }, 245 | { 246 | "name": "variable.other.wasm", 247 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 248 | }, 249 | { 250 | "include": "#typeUse" 251 | }, 252 | { 253 | "include": "#funcTypeParams" 254 | }, 255 | { 256 | "include": "#funcTypeResults" 257 | }, 258 | { 259 | "include": "#instrList" 260 | } 261 | ] 262 | }, 263 | "comment": { 264 | "name": "meta.comment.wasm", 265 | "patterns": [ 266 | { 267 | "include": "#lineComment" 268 | }, 269 | { 270 | "include": "#blockComment" 271 | } 272 | ] 273 | }, 274 | "elemType": { 275 | "name": "meta.elemType.wasm storage.type.wasm", 276 | "match": "\\bfuncref\\b" 277 | }, 278 | "exportDesc": { 279 | "name": "meta.exportDesc.wasm", 280 | "patterns": [ 281 | { 282 | "include": "#exportDescFunc" 283 | }, 284 | { 285 | "include": "#exportDescTable" 286 | }, 287 | { 288 | "include": "#exportDescMemory" 289 | }, 290 | { 291 | "include": "#exportDescGlobal" 292 | } 293 | ] 294 | }, 295 | "exportDescFunc": { 296 | "name": "meta.exportDescFunc.wasm", 297 | "begin": "\\bfunc\\b", 298 | "beginCaptures": { 299 | "0": { 300 | "name": "keyword.control.func.wasm" 301 | } 302 | }, 303 | "end": "(?=\\))", 304 | "patterns": [ 305 | { 306 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 307 | } 308 | ] 309 | }, 310 | "exportDescGlobal": { 311 | "name": "meta.exportDescGlobal.wasm", 312 | "begin": "\\bglobal(?!\\.)\\b", 313 | "beginCaptures": { 314 | "0": { 315 | "name": "keyword.control.global.wasm" 316 | } 317 | }, 318 | "end": "(?=\\))", 319 | "patterns": [ 320 | { 321 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 322 | } 323 | ] 324 | }, 325 | "exportDescMemory": { 326 | "name": "meta.exportDescMemory.wasm", 327 | "begin": "\\bmemory(?!\\.)\\b", 328 | "beginCaptures": { 329 | "0": { 330 | "name": "keyword.control.memory.wasm" 331 | } 332 | }, 333 | "end": "(?=\\))", 334 | "patterns": [ 335 | { 336 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 337 | } 338 | ] 339 | }, 340 | "exportDescTable": { 341 | "name": "meta.exportDescTable.wasm", 342 | "begin": "\\btable\\b", 343 | "beginCaptures": { 344 | "0": { 345 | "name": "keyword.control.table.wasm" 346 | } 347 | }, 348 | "end": "(?=\\))", 349 | "patterns": [ 350 | { 351 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 352 | } 353 | ] 354 | }, 355 | "expr": { 356 | "name": "meta.expr.wasm", 357 | "patterns": [ 358 | { 359 | "include": "#exprPlain" 360 | }, 361 | { 362 | "include": "#exprCall" 363 | }, 364 | { 365 | "include": "#exprBlock" 366 | }, 367 | { 368 | "include": "#exprLoop" 369 | }, 370 | { 371 | "include": "#exprIf" 372 | }, 373 | { 374 | "begin": "\\(", 375 | "beginCaptures": { 376 | "0": { 377 | "name": "meta.brace.round.wasm" 378 | } 379 | }, 380 | "end": "\\)", 381 | "endCaptures": { 382 | "0": { 383 | "name": "meta.brace.round.wasm" 384 | } 385 | }, 386 | "patterns": [ 387 | { 388 | "include": "#expr" 389 | } 390 | ] 391 | } 392 | ] 393 | }, 394 | "exprBlock": { 395 | "name": "meta.exprBlock.wasm", 396 | "begin": "\\bblock\\b", 397 | "beginCaptures": { 398 | "0": { 399 | "name": "keyword.control.wasm" 400 | } 401 | }, 402 | "end": "(?=\\))", 403 | "patterns": [ 404 | { 405 | "include": "#extra" 406 | }, 407 | { 408 | "name": "variable.other.wasm", 409 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 410 | }, 411 | { 412 | "begin": "\\(", 413 | "beginCaptures": { 414 | "0": { 415 | "name": "meta.brace.round.wasm" 416 | } 417 | }, 418 | "end": "\\)", 419 | "endCaptures": { 420 | "0": { 421 | "name": "meta.brace.round.wasm" 422 | } 423 | }, 424 | "patterns": [ 425 | { 426 | "include": "#extra" 427 | }, 428 | { 429 | "include": "#typeUse" 430 | }, 431 | { 432 | "include": "#funcTypeParams" 433 | }, 434 | { 435 | "include": "#funcTypeResults" 436 | }, 437 | { 438 | "include": "#expr" 439 | } 440 | ] 441 | }, 442 | { 443 | "include": "#instrList" 444 | } 445 | ] 446 | }, 447 | "exprCall": { 448 | "name": "meta.exprCall.wasm", 449 | "patterns": [ 450 | { 451 | "name": "keyword.control.wasm", 452 | "match": "\\bcall_indirect\\b" 453 | } 454 | ] 455 | }, 456 | "exprIf": { 457 | "name": "meta.exprIf.wasm", 458 | "patterns": [ 459 | { 460 | "name": "keyword.control.wasm", 461 | "match": "\\bif\\b" 462 | }, 463 | { 464 | "name": "keyword.control.wasm", 465 | "match": "\\belse|then\\b" 466 | } 467 | ] 468 | }, 469 | "exprLoop": { 470 | "name": "meta.exprLoop.wasm", 471 | "patterns": [ 472 | { 473 | "name": "keyword.control.wasm", 474 | "match": "\\bloop\\b" 475 | } 476 | ] 477 | }, 478 | "exprPlain": { 479 | "name": "meta.exprPlain.wasm", 480 | "patterns": [ 481 | { 482 | "include": "#instrPlain" 483 | }, 484 | { 485 | "begin": "\\(", 486 | "beginCaptures": { 487 | "0": { 488 | "name": "meta.brace.round.wasm" 489 | } 490 | }, 491 | "end": "\\)", 492 | "endCaptures": { 493 | "0": { 494 | "name": "meta.brace.round.wasm" 495 | } 496 | }, 497 | "patterns": [ 498 | { 499 | "include": "#expr" 500 | } 501 | ] 502 | } 503 | ] 504 | }, 505 | "extra": { 506 | "name": "meta.extra.wasm", 507 | "patterns": [ 508 | { 509 | "include": "#comment" 510 | }, 511 | { 512 | "include": "#annotation" 513 | } 514 | ] 515 | }, 516 | "funcLocals": { 517 | "name": "meta.funcLocals.wasm", 518 | "begin": "\\blocal(?!\\.)\\b", 519 | "beginCaptures": { 520 | "0": { 521 | "name": "keyword.control.local.wasm" 522 | } 523 | }, 524 | "end": "(?=\\))", 525 | "patterns": [ 526 | { 527 | "name": "variable.parameter.local.wasm", 528 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 529 | }, 530 | { 531 | "include": "#valueType" 532 | } 533 | ] 534 | }, 535 | "funcType": { 536 | "name": "meta.funcType.wasm", 537 | "patterns": [ 538 | { 539 | "include": "#funcTypeParams" 540 | }, 541 | { 542 | "include": "#funcTypeResults" 543 | } 544 | ] 545 | }, 546 | "funcTypeParams": { 547 | "name": "meta.funcTypeParams.wasm", 548 | "begin": "\\bparam\\b", 549 | "beginCaptures": { 550 | "0": { 551 | "name": "keyword.control.param.wasm" 552 | } 553 | }, 554 | "end": "(?=\\))", 555 | "patterns": [ 556 | { 557 | "include": "#extra" 558 | }, 559 | { 560 | "include": "#valueType" 561 | }, 562 | { 563 | "name": "entity.name.type.alias.wasm", 564 | "match": "[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 565 | } 566 | ] 567 | }, 568 | "funcTypeResults": { 569 | "name": "meta.funcTypeResults.wasm", 570 | "begin": "\\bresult\\b", 571 | "beginCaptures": { 572 | "0": { 573 | "name": "keyword.control.param.wasm" 574 | } 575 | }, 576 | "end": "(?=\\))", 577 | "patterns": [ 578 | { 579 | "include": "#extra" 580 | }, 581 | { 582 | "include": "#valueType" 583 | } 584 | ] 585 | }, 586 | "globalType": { 587 | "name": "meta.globalType.wasm", 588 | "patterns": [ 589 | { 590 | "include": "#globalTypeImm" 591 | }, 592 | { 593 | "include": "#globalTypeMut" 594 | } 595 | ] 596 | }, 597 | "globalTypeImm": { 598 | "name": "meta.globalTypeImm.wasm", 599 | "patterns": [ 600 | { 601 | "include": "#valueType" 602 | } 603 | ] 604 | }, 605 | "globalTypeMut": { 606 | "name": "meta.globalTypeMut.wasm", 607 | "patterns": [ 608 | { 609 | "begin": "\\(", 610 | "beginCaptures": { 611 | "0": { 612 | "name": "meta.brace.round.wasm" 613 | } 614 | }, 615 | "end": "\\)", 616 | "endCaptures": { 617 | "0": { 618 | "name": "meta.brace.round.wasm" 619 | } 620 | }, 621 | "patterns": [ 622 | { 623 | "include": "#extra" 624 | }, 625 | { 626 | "begin": "(?<=\\()", 627 | "end": "\\bmut\\b", 628 | "endCaptures": { 629 | "0": { 630 | "name": "storage.modifier.wasm" 631 | } 632 | }, 633 | "patterns": [ 634 | { 635 | "include": "#extra" 636 | }, 637 | { 638 | "include": "#valueType" 639 | } 640 | ] 641 | } 642 | ] 643 | } 644 | ] 645 | }, 646 | "importDesc": { 647 | "name": "meta.importDesc.wasm", 648 | "begin": "\\(", 649 | "beginCaptures": { 650 | "0": { 651 | "name": "meta.brace.round.wasm" 652 | } 653 | }, 654 | "end": "\\)", 655 | "endCaptures": { 656 | "0": { 657 | "name": "meta.brace.round.wasm" 658 | } 659 | }, 660 | "patterns": [ 661 | { 662 | "include": "#importDescFuncType" 663 | }, 664 | { 665 | "include": "#importDescGlobalType" 666 | }, 667 | { 668 | "include": "#importDescMemoryType" 669 | }, 670 | { 671 | "include": "#importDescTableType" 672 | } 673 | ] 674 | }, 675 | "importDescFuncType": { 676 | "name": "meta.importDescFuncType.wasm", 677 | "begin": "\\bfunc\\b", 678 | "beginCaptures": { 679 | "0": { 680 | "name": "keyword.control.func.wasm" 681 | } 682 | }, 683 | "end": "(?=\\))", 684 | "patterns": [ 685 | { 686 | "name": "entity.name.function.wasm", 687 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 688 | }, 689 | { 690 | "begin": "\\(", 691 | "end": "\\)", 692 | "patterns": [ 693 | { 694 | "include": "#funcType" 695 | }, 696 | { 697 | "include": "#typeUse" 698 | } 699 | ] 700 | } 701 | ] 702 | }, 703 | "importDescGlobalType": { 704 | "name": "meta.importDescGlobalType.wasm", 705 | "begin": "\\bglobal(?!\\.)\\b", 706 | "beginCaptures": { 707 | "0": { 708 | "name": "keyword.control.global.wasm" 709 | } 710 | }, 711 | "end": "(?=\\))", 712 | "patterns": [ 713 | { 714 | "name": "variable.other.global.wasm", 715 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 716 | }, 717 | { 718 | "include": "#globalType" 719 | } 720 | ] 721 | }, 722 | "importDescMemoryType": { 723 | "name": "meta.importDescMemoryType.wasm", 724 | "begin": "\\bmemory(?!\\.)\\b", 725 | "beginCaptures": { 726 | "0": { 727 | "name": "keyword.control.memory.wasm" 728 | } 729 | }, 730 | "end": "(?=\\))", 731 | "patterns": [ 732 | { 733 | "name": "variable.other.memory.wasm", 734 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 735 | }, 736 | { 737 | "include": "#memoryType" 738 | } 739 | ] 740 | }, 741 | "importDescTableType": { 742 | "name": "meta.importDescTableType.wasm", 743 | "begin": "\\btable\\b", 744 | "beginCaptures": { 745 | "0": { 746 | "name": "keyword.control.table.wasm" 747 | } 748 | }, 749 | "end": "(?=\\))", 750 | "patterns": [ 751 | { 752 | "name": "variable.other.table.wasm", 753 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 754 | }, 755 | { 756 | "include": "#tableType" 757 | } 758 | ] 759 | }, 760 | "inlineExport": { 761 | "name": "meta.inlineExport.wasm", 762 | "begin": "\\bexport\\b", 763 | "beginCaptures": { 764 | "0": { 765 | "name": "keyword.control.export.wasm" 766 | } 767 | }, 768 | "end": "(?=\\))", 769 | "patterns": [ 770 | { 771 | "include": "#extra" 772 | }, 773 | { 774 | "name": "variable.other.readwrite.alias.wasm", 775 | "begin": "\"", 776 | "end": "(\")|((?:[^\\\\\\n])$)", 777 | "patterns": [ 778 | { 779 | "match": "\\\\([0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\}|[\\\\'\\\\\"ntr]|$)" 780 | } 781 | ] 782 | } 783 | ] 784 | }, 785 | "inlineImport": { 786 | "name": "meta.inlineImport.wasm", 787 | "begin": "\\bimport\\b", 788 | "beginCaptures": { 789 | "0": { 790 | "name": "keyword.control.import.wasm" 791 | } 792 | }, 793 | "end": "(?=\\))", 794 | "patterns": [ 795 | { 796 | "include": "#extra" 797 | }, 798 | { 799 | "include": "#inlineImportNames" 800 | } 801 | ] 802 | }, 803 | "inlineImportNames": { 804 | "name": "meta.inlineImportNames.wasm", 805 | "patterns": [ 806 | { 807 | "begin": "(?:(?<=(?:[^[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+]import|^import))(?![0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+))", 808 | "end": "(?<=\")", 809 | "patterns": [ 810 | { 811 | "include": "#extra" 812 | }, 813 | { 814 | "name": "entity.name.type.module.wasm", 815 | "begin": "\"", 816 | "end": "(\")|((?:[^\\\\\\n])$)", 817 | "patterns": [ 818 | { 819 | "match": "\\\\([0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\}|[\\\\'\\\\\"ntr]|$)" 820 | } 821 | ] 822 | } 823 | ] 824 | }, 825 | { 826 | "name": "variable.other.readwrite.alias.wasm", 827 | "begin": "\"", 828 | "end": "(\")|((?:[^\\\\\\n])$)", 829 | "patterns": [ 830 | { 831 | "match": "\\\\([0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\}|[\\\\'\\\\\"ntr]|$)" 832 | } 833 | ] 834 | } 835 | ] 836 | }, 837 | "instr": { 838 | "name": "meta.instr.wasm", 839 | "patterns": [ 840 | { 841 | "include": "#instrPlain" 842 | }, 843 | { 844 | "include": "#instrCall" 845 | }, 846 | { 847 | "include": "#instrBlock" 848 | }, 849 | { 850 | "begin": "\\(", 851 | "beginCaptures": { 852 | "0": { 853 | "name": "meta.brace.round.wasm" 854 | } 855 | }, 856 | "end": "\\)", 857 | "endCaptures": { 858 | "0": { 859 | "name": "meta.brace.round.wasm" 860 | } 861 | }, 862 | "patterns": [ 863 | { 864 | "include": "#expr" 865 | } 866 | ] 867 | } 868 | ] 869 | }, 870 | "instrBlock": { 871 | "name": "meta.instrBlock.wasm", 872 | "patterns": [ 873 | { 874 | "include": "#blockBlock" 875 | }, 876 | { 877 | "include": "#blockLoop" 878 | }, 879 | { 880 | "include": "#blockIf" 881 | } 882 | ] 883 | }, 884 | "instrCall": { 885 | "name": "meta.instrCall.wasm", 886 | "patterns": [] 887 | }, 888 | "instrList": { 889 | "name": "meta.instrList.wasm", 890 | "patterns": [ 891 | { 892 | "include": "#instrListCall" 893 | }, 894 | { 895 | "include": "#instr" 896 | } 897 | ] 898 | }, 899 | "instrPlain": { 900 | "name": "meta.instrPlain.wasm", 901 | "patterns": [ 902 | { 903 | "include": "#instrPlainUnreachable" 904 | }, 905 | { 906 | "include": "#instrPlainNop" 907 | }, 908 | { 909 | "include": "#instrPlainDrop" 910 | }, 911 | { 912 | "include": "#instrPlainSelect" 913 | }, 914 | { 915 | "include": "#instrPlainBr" 916 | }, 917 | { 918 | "include": "#instrPlainBrIf" 919 | }, 920 | { 921 | "include": "#instrPlainBrTable" 922 | }, 923 | { 924 | "include": "#instrPlainReturn" 925 | }, 926 | { 927 | "include": "#instrPlainLocalGet" 928 | }, 929 | { 930 | "include": "#instrPlainLocalSet" 931 | }, 932 | { 933 | "include": "#instrPlainLocalTee" 934 | }, 935 | { 936 | "include": "#instrPlainGlobalGet" 937 | }, 938 | { 939 | "include": "#instrPlainGlobalSet" 940 | }, 941 | { 942 | "include": "#instrPlainMemorySize" 943 | }, 944 | { 945 | "include": "#instrPlainMemoryGrow" 946 | }, 947 | { 948 | "include": "#instrPlainConst" 949 | }, 950 | { 951 | "include": "#instrPlainTest" 952 | }, 953 | { 954 | "include": "#instrPlainCompare" 955 | }, 956 | { 957 | "include": "#instrPlainUnary" 958 | }, 959 | { 960 | "include": "#instrPlainBinary" 961 | }, 962 | { 963 | "include": "#instrPlainConvert" 964 | }, 965 | { 966 | "include": "#instrPlainLoad" 967 | }, 968 | { 969 | "include": "#instrPlainStore" 970 | }, 971 | { 972 | "include": "#instrPlainCall" 973 | } 974 | ] 975 | }, 976 | "instrPlainBinary": { 977 | "name": "meta.instrPlainBinary.wasm", 978 | "patterns": [ 979 | { 980 | "name": "keyword.control.wasm", 981 | "match": "\\b(?:i(?:32|64)|f(?:32|64))\\b(??@\\^_'|~]+)", 1006 | "endCaptures": { 1007 | "0": { 1008 | "name": "variable.other.constant" 1009 | } 1010 | } 1011 | }, 1012 | "instrPlainBrIf": { 1013 | "name": "meta.instrPlainBrIf.wasm", 1014 | "begin": "\\bbr_if\\b", 1015 | "beginCaptures": { 1016 | "0": { 1017 | "name": "keyword.control.wasm" 1018 | } 1019 | }, 1020 | "end": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)", 1021 | "endCaptures": { 1022 | "0": { 1023 | "name": "variable.other.constant" 1024 | } 1025 | } 1026 | }, 1027 | "instrPlainBrTable": { 1028 | "name": "meta.instrPlainBrTable.wasm", 1029 | "begin": "\\bbr_table\\b", 1030 | "beginCaptures": { 1031 | "0": { 1032 | "name": "keyword.control.wasm" 1033 | } 1034 | }, 1035 | "end": "(?![[:space:]]|$|(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+))", 1036 | "patterns": [ 1037 | { 1038 | "name": "variable.other.constant", 1039 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 1040 | } 1041 | ] 1042 | }, 1043 | "instrPlainCall": { 1044 | "name": "meta.instrPlainCall.wasm", 1045 | "begin": "\\bcall\\b", 1046 | "beginCaptures": { 1047 | "0": { 1048 | "name": "keyword.control.wasm" 1049 | } 1050 | }, 1051 | "end": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)", 1052 | "endCaptures": { 1053 | "0": { 1054 | "name": "variable.other.constant" 1055 | } 1056 | } 1057 | }, 1058 | "instrPlainCompare": { 1059 | "name": "meta.instrPlainCompare.wasm", 1060 | "patterns": [ 1061 | { 1062 | "name": "keyword.control.wasm", 1063 | "match": "\\b(?:i(?:32|64)|f(?:32|64))\\b(??@\\^_'|~]+)", 1160 | "endCaptures": { 1161 | "0": { 1162 | "name": "variable.other.constant" 1163 | } 1164 | } 1165 | }, 1166 | "instrPlainGlobalSet": { 1167 | "name": "meta.instrPlainGlobalSet.wasm", 1168 | "begin": "\\bglobal\\.set\\b", 1169 | "beginCaptures": { 1170 | "0": { 1171 | "name": "keyword.control.wasm" 1172 | } 1173 | }, 1174 | "end": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)", 1175 | "endCaptures": { 1176 | "0": { 1177 | "name": "variable.other.constant" 1178 | } 1179 | } 1180 | }, 1181 | "instrPlainLoad": { 1182 | "name": "meta.instrPlainLoad.wasm", 1183 | "patterns": [ 1184 | { 1185 | "begin": "\\bi64\\b(??@\\^_'|~]+)", 1246 | "endCaptures": { 1247 | "0": { 1248 | "name": "variable.other.constant" 1249 | } 1250 | } 1251 | }, 1252 | "instrPlainLocalSet": { 1253 | "name": "meta.instrPlainLocalSet.wasm", 1254 | "begin": "\\blocal\\.set\\b", 1255 | "beginCaptures": { 1256 | "0": { 1257 | "name": "keyword.control.wasm" 1258 | } 1259 | }, 1260 | "end": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)", 1261 | "endCaptures": { 1262 | "0": { 1263 | "name": "variable.other.constant" 1264 | } 1265 | } 1266 | }, 1267 | "instrPlainLocalTee": { 1268 | "name": "meta.instrPlainLocalTee.wasm", 1269 | "begin": "\\blocal\\.tee\\b", 1270 | "beginCaptures": { 1271 | "0": { 1272 | "name": "keyword.control.wasm" 1273 | } 1274 | }, 1275 | "end": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)", 1276 | "endCaptures": { 1277 | "0": { 1278 | "name": "variable.other.constant" 1279 | } 1280 | } 1281 | }, 1282 | "instrPlainMemorySize": { 1283 | "name": "meta.instrPlainMemorySize.wasm keyword.control.wasm", 1284 | "match": "\\bmemory\\.size\\b" 1285 | }, 1286 | "instrPlainMemoryGrow": { 1287 | "name": "meta.instrPlainMemoryGrow.wasm keyword.control.wasm", 1288 | "match": "\\bmemory\\.grow\\b" 1289 | }, 1290 | "instrPlainNop": { 1291 | "name": "meta.instrPlainNop.wasm keyword.control.wasm", 1292 | "match": "\\bnop\\b" 1293 | }, 1294 | "instrPlainReturn": { 1295 | "name": "meta.instrPlainReturn.wasm keyword.control.wasm", 1296 | "match": "\\breturn\\b" 1297 | }, 1298 | "instrPlainSelect": { 1299 | "name": "meta.instrPlainSelect.wasm keyword.control.wasm", 1300 | "match": "\\bselect\\b" 1301 | }, 1302 | "instrPlainStore": { 1303 | "name": "meta.instrPlainStore.wasm", 1304 | "patterns": [ 1305 | { 1306 | "begin": "\\bi64\\b(??@\\^_'|~]+", 1457 | "beginCaptures": { 1458 | "0": { 1459 | "name": "entity.name.type.module.wasm" 1460 | } 1461 | }, 1462 | "end": "(?=\\))", 1463 | "patterns": [ 1464 | { 1465 | "include": "#extra" 1466 | }, 1467 | { 1468 | "include": "#moduleField" 1469 | } 1470 | ] 1471 | }, 1472 | { 1473 | "include": "#moduleField" 1474 | } 1475 | ] 1476 | }, 1477 | "moduleField": { 1478 | "name": "meta.moduleField.wasm", 1479 | "patterns": [ 1480 | { 1481 | "include": "#extra" 1482 | }, 1483 | { 1484 | "include": "#moduleFieldData" 1485 | }, 1486 | { 1487 | "include": "#moduleFieldElem" 1488 | }, 1489 | { 1490 | "include": "#moduleFieldExport" 1491 | }, 1492 | { 1493 | "include": "#moduleFieldFunc" 1494 | }, 1495 | { 1496 | "include": "#moduleFieldGlobal" 1497 | }, 1498 | { 1499 | "include": "#moduleFieldImport" 1500 | }, 1501 | { 1502 | "include": "#moduleFieldMemory" 1503 | }, 1504 | { 1505 | "include": "#moduleFieldStart" 1506 | }, 1507 | { 1508 | "include": "#moduleFieldTable" 1509 | }, 1510 | { 1511 | "include": "#moduleFieldType" 1512 | } 1513 | ] 1514 | }, 1515 | "moduleFieldData": { 1516 | "name": "meta.moduleFieldData.wasm", 1517 | "begin": "\\bdata\\b", 1518 | "beginCaptures": { 1519 | "0": { 1520 | "name": "storage.type.data.wasm" 1521 | } 1522 | }, 1523 | "end": "(?=\\))", 1524 | "patterns": [ 1525 | { 1526 | "include": "#extra" 1527 | }, 1528 | { 1529 | "name": "variable.other.constant entity.name.data.wasm", 1530 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 1531 | }, 1532 | { 1533 | "include": "#offset" 1534 | }, 1535 | { 1536 | "include": "#string" 1537 | } 1538 | ] 1539 | }, 1540 | "moduleFieldElem": { 1541 | "name": "meta.moduleFieldElem.wasm", 1542 | "begin": "\\belem\\b", 1543 | "beginCaptures": { 1544 | "0": { 1545 | "name": "storage.type.elem.wasm" 1546 | } 1547 | }, 1548 | "end": "(?=\\))", 1549 | "patterns": [ 1550 | { 1551 | "include": "#extra" 1552 | }, 1553 | { 1554 | "include": "#offset" 1555 | }, 1556 | { 1557 | "name": "variable.other.wasm", 1558 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 1559 | } 1560 | ] 1561 | }, 1562 | "moduleFieldExport": { 1563 | "name": "meta.moduleFieldExport.wasm", 1564 | "begin": "\\bexport\\b", 1565 | "beginCaptures": { 1566 | "0": { 1567 | "name": "keyword.control.export.wasm" 1568 | } 1569 | }, 1570 | "end": "(?=\\))", 1571 | "patterns": [ 1572 | { 1573 | "include": "#extra" 1574 | }, 1575 | { 1576 | "name": "variable.other.readwrite.alias.wasm", 1577 | "begin": "\"", 1578 | "end": "(\")|((?:[^\\\\\\n])$)", 1579 | "patterns": [ 1580 | { 1581 | "match": "\\\\([0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\}|[\\\\'\\\\\"ntr]|$)" 1582 | } 1583 | ] 1584 | }, 1585 | { 1586 | "begin": "\\(", 1587 | "beginCaptures": { 1588 | "0": { 1589 | "name": "meta.brace.round.wasm" 1590 | } 1591 | }, 1592 | "end": "\\)", 1593 | "endCaptures": { 1594 | "0": { 1595 | "name": "meta.brace.round.wasm" 1596 | } 1597 | }, 1598 | "patterns": [ 1599 | { 1600 | "include": "#exportDesc" 1601 | } 1602 | ] 1603 | } 1604 | ] 1605 | }, 1606 | "moduleFieldFunc": { 1607 | "name": "meta.moduleFieldFunc.wasm", 1608 | "begin": "\\bfunc\\b", 1609 | "beginCaptures": { 1610 | "0": { 1611 | "name": "storage.type.function.wasm" 1612 | } 1613 | }, 1614 | "end": "(?=\\))", 1615 | "patterns": [ 1616 | { 1617 | "include": "#extra" 1618 | }, 1619 | { 1620 | "name": "entity.name.function.wasm", 1621 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 1622 | }, 1623 | { 1624 | "begin": "\\(", 1625 | "beginCaptures": { 1626 | "0": { 1627 | "name": "meta.brace.round.wasm" 1628 | } 1629 | }, 1630 | "end": "\\)", 1631 | "endCaptures": { 1632 | "0": { 1633 | "name": "meta.brace.round.wasm" 1634 | } 1635 | }, 1636 | "patterns": [ 1637 | { 1638 | "include": "#inlineExport" 1639 | }, 1640 | { 1641 | "include": "#inlineImport" 1642 | }, 1643 | { 1644 | "include": "#typeUse" 1645 | }, 1646 | { 1647 | "include": "#funcTypeParams" 1648 | }, 1649 | { 1650 | "include": "#funcTypeResults" 1651 | }, 1652 | { 1653 | "include": "#funcLocals" 1654 | }, 1655 | { 1656 | "include": "#expr" 1657 | } 1658 | ] 1659 | }, 1660 | { 1661 | "include": "#instrList" 1662 | } 1663 | ] 1664 | }, 1665 | "moduleFieldGlobal": { 1666 | "name": "meta.moduleFieldGlobal.wasm", 1667 | "begin": "\\bglobal(?!\\.)\\b", 1668 | "beginCaptures": { 1669 | "0": { 1670 | "name": "storage.type.global.wasm" 1671 | } 1672 | }, 1673 | "end": "(?=\\))", 1674 | "patterns": [ 1675 | { 1676 | "include": "#extra" 1677 | }, 1678 | { 1679 | "name": "variable.other.global.wasm", 1680 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 1681 | }, 1682 | { 1683 | "begin": "\\(", 1684 | "beginCaptures": { 1685 | "0": { 1686 | "name": "meta.brace.round.wasm" 1687 | } 1688 | }, 1689 | "end": "\\)", 1690 | "endCaptures": { 1691 | "0": { 1692 | "name": "meta.brace.round.wasm" 1693 | } 1694 | }, 1695 | "patterns": [ 1696 | { 1697 | "include": "#extra" 1698 | }, 1699 | { 1700 | "include": "#inlineExport" 1701 | }, 1702 | { 1703 | "include": "#inlineImport" 1704 | } 1705 | ] 1706 | }, 1707 | { 1708 | "include": "#globalType" 1709 | }, 1710 | { 1711 | "include": "#expr" 1712 | } 1713 | ] 1714 | }, 1715 | "moduleFieldImport": { 1716 | "name": "meta.moduleFieldImport.wasm", 1717 | "begin": "\\bimport\\b", 1718 | "beginCaptures": { 1719 | "0": { 1720 | "name": "keyword.control.import.wasm" 1721 | } 1722 | }, 1723 | "end": "(?=\\))", 1724 | "patterns": [ 1725 | { 1726 | "include": "#extra" 1727 | }, 1728 | { 1729 | "include": "#inlineImportNames" 1730 | }, 1731 | { 1732 | "include": "#importDesc" 1733 | } 1734 | ] 1735 | }, 1736 | "moduleFieldMemory": { 1737 | "name": "meta.moduleFieldMemory.wasm", 1738 | "begin": "\\bmemory(?!\\.)\\b", 1739 | "beginCaptures": { 1740 | "0": { 1741 | "name": "storage.type.memory.wasm" 1742 | } 1743 | }, 1744 | "end": "(?=\\))", 1745 | "patterns": [ 1746 | { 1747 | "include": "#extra" 1748 | }, 1749 | { 1750 | "name": "variable.other.memory.wasm", 1751 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 1752 | }, 1753 | { 1754 | "include": "#memoryFieldsType" 1755 | }, 1756 | { 1757 | "begin": "\\(", 1758 | "beginCaptures": { 1759 | "0": { 1760 | "name": "meta.brace.round.wasm" 1761 | } 1762 | }, 1763 | "end": "\\)", 1764 | "endCaptures": { 1765 | "0": { 1766 | "name": "meta.brace.round.wasm" 1767 | } 1768 | }, 1769 | "patterns": [ 1770 | { 1771 | "include": "#inlineExport" 1772 | }, 1773 | { 1774 | "include": "#memoryFieldsData" 1775 | } 1776 | ] 1777 | } 1778 | ] 1779 | }, 1780 | "moduleFieldStart": { 1781 | "name": "meta.moduleFieldStart.wasm", 1782 | "begin": "\\bstart\\b", 1783 | "beginCaptures": { 1784 | "0": { 1785 | "name": "keyword.control.start.wasm" 1786 | } 1787 | }, 1788 | "end": "(?=\\))", 1789 | "patterns": [ 1790 | { 1791 | "include": "#extra" 1792 | }, 1793 | { 1794 | "begin": "[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+", 1795 | "beginCaptures": { 1796 | "0": { 1797 | "name": "entity.name.function.wasm" 1798 | } 1799 | }, 1800 | "end": "(?=\\))" 1801 | } 1802 | ] 1803 | }, 1804 | "moduleFieldTable": { 1805 | "name": "meta.moduleFieldTable.wasm", 1806 | "begin": "\\btable\\b", 1807 | "beginCaptures": { 1808 | "0": { 1809 | "name": "storage.type.table.wasm" 1810 | } 1811 | }, 1812 | "end": "(?=\\))", 1813 | "patterns": [ 1814 | { 1815 | "include": "#extra" 1816 | }, 1817 | { 1818 | "name": "variable.other.table.wasm", 1819 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 1820 | }, 1821 | { 1822 | "patterns": [ 1823 | { 1824 | "include": "#limits" 1825 | }, 1826 | { 1827 | "include": "#elemType" 1828 | } 1829 | ] 1830 | }, 1831 | { 1832 | "begin": "\\(", 1833 | "beginCaptures": { 1834 | "0": { 1835 | "name": "meta.brace.round.wasm" 1836 | } 1837 | }, 1838 | "end": "\\)", 1839 | "endCaptures": { 1840 | "0": { 1841 | "name": "meta.brace.round.wasm" 1842 | } 1843 | }, 1844 | "patterns": [ 1845 | { 1846 | "include": "#extra" 1847 | }, 1848 | { 1849 | "include": "#inlineExport" 1850 | }, 1851 | { 1852 | "include": "#tableFieldsElem" 1853 | }, 1854 | { 1855 | "include": "#tableFieldsType" 1856 | } 1857 | ] 1858 | } 1859 | ] 1860 | }, 1861 | "moduleFieldType": { 1862 | "name": "meta.moduleFieldType.wasm", 1863 | "begin": "\\btype\\b", 1864 | "beginCaptures": { 1865 | "0": { 1866 | "name": "storage.type.type.wasm" 1867 | } 1868 | }, 1869 | "end": "(?=\\))", 1870 | "patterns": [ 1871 | { 1872 | "include": "#extra" 1873 | }, 1874 | { 1875 | "name": "entity.name.type.alias.wasm", 1876 | "match": "\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+" 1877 | }, 1878 | { 1879 | "include": "#typeField" 1880 | } 1881 | ] 1882 | }, 1883 | "name": { 1884 | "name": "meta.name.wasm", 1885 | "patterns": [ 1886 | { 1887 | "include": "#string" 1888 | } 1889 | ] 1890 | }, 1891 | "offset": { 1892 | "name": "meta.offset.wasm", 1893 | "begin": "\\(", 1894 | "beginCaptures": { 1895 | "0": { 1896 | "name": "meta.brace.round.wasm" 1897 | } 1898 | }, 1899 | "end": "\\)", 1900 | "endCaptures": { 1901 | "0": { 1902 | "name": "meta.brace.round.wasm" 1903 | } 1904 | }, 1905 | "patterns": [ 1906 | { 1907 | "include": "#offsetConstExpr" 1908 | }, 1909 | { 1910 | "include": "#offsetExpr" 1911 | } 1912 | ] 1913 | }, 1914 | "offsetConstExpr": { 1915 | "name": "meta.offsetConstExpr.wasm", 1916 | "begin": "\\boffset\\b", 1917 | "beginCaptures": { 1918 | "0": { 1919 | "name": "storage.type.type.wasm" 1920 | } 1921 | }, 1922 | "end": "(?=\\))", 1923 | "patterns": [ 1924 | { 1925 | "include": "#instr" 1926 | } 1927 | ] 1928 | }, 1929 | "offsetExpr": { 1930 | "name": "meta.offsetExpr.wasm", 1931 | "patterns": [ 1932 | { 1933 | "include": "#expr" 1934 | } 1935 | ] 1936 | }, 1937 | "offsetValue": { 1938 | "begin": "[[:space:]]+(\\boffset=(?:[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)\\b)", 1939 | "end": "(?!\\G)|(?![[:space:]])", 1940 | "beginCaptures": { 1941 | "1": { 1942 | "name": "storage.modifier.wasm" 1943 | } 1944 | }, 1945 | "patterns": [ 1946 | { 1947 | "include": "#alignValue" 1948 | } 1949 | ] 1950 | }, 1951 | "string": { 1952 | "name": "meta.string.wasm string.quoted.double.wasm", 1953 | "begin": "\"", 1954 | "beginCaptures": { 1955 | "0": { 1956 | "name": "punctuation.definition.string.begin.wasm" 1957 | } 1958 | }, 1959 | "end": "(\")|((?:[^\\\\\\n])$)", 1960 | "endCaptures": { 1961 | "1": { 1962 | "name": "punctuation.definition.string.end.wasm" 1963 | }, 1964 | "2": { 1965 | "name": "invalid.illegal.newline.wasm" 1966 | } 1967 | }, 1968 | "patterns": [ 1969 | { 1970 | "include": "#stringCharacterEscape" 1971 | } 1972 | ] 1973 | }, 1974 | "stringCharacterEscape": { 1975 | "name": "meta.stringCharacterEscape.wasm constant.character.escape.wasm", 1976 | "match": "\\\\([0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\}|[\\\\'\\\\\"ntr]|$)" 1977 | }, 1978 | "tableFieldsElem": { 1979 | "name": "meta.tableFieldsElem.wasm", 1980 | "begin": "\\belem\\b", 1981 | "beginCaptures": { 1982 | "0": { 1983 | "name": "storage.type.elem.wasm" 1984 | } 1985 | }, 1986 | "end": "(?=\\))", 1987 | "patterns": [ 1988 | { 1989 | "include": "#extra" 1990 | }, 1991 | { 1992 | "name": "variable.other.constant", 1993 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 1994 | } 1995 | ] 1996 | }, 1997 | "tableFieldsType": { 1998 | "name": "meta.tableFieldsType.wasm", 1999 | "patterns": [ 2000 | { 2001 | "include": "#inlineImport" 2002 | }, 2003 | { 2004 | "include": "#tableType" 2005 | } 2006 | ] 2007 | }, 2008 | "tableType": { 2009 | "name": "meta.tableType.wasm", 2010 | "patterns": [ 2011 | { 2012 | "include": "#limits" 2013 | }, 2014 | { 2015 | "include": "#elemType" 2016 | } 2017 | ] 2018 | }, 2019 | "typeField": { 2020 | "name": "meta.typeField.wasm", 2021 | "begin": "\\(", 2022 | "beginCaptures": { 2023 | "0": { 2024 | "name": "meta.brace.round.wasm" 2025 | } 2026 | }, 2027 | "end": "\\)", 2028 | "endCaptures": { 2029 | "0": { 2030 | "name": "meta.brace.round.wasm" 2031 | } 2032 | }, 2033 | "patterns": [ 2034 | { 2035 | "include": "#extra" 2036 | }, 2037 | { 2038 | "begin": "(?<=\\()", 2039 | "end": "\\bfunc\\b", 2040 | "endCaptures": { 2041 | "0": { 2042 | "name": "storage.type.function.wasm" 2043 | } 2044 | } 2045 | }, 2046 | { 2047 | "begin": "\\(", 2048 | "beginCaptures": { 2049 | "0": { 2050 | "name": "meta.brace.round.wasm" 2051 | } 2052 | }, 2053 | "end": "\\)", 2054 | "endCaptures": { 2055 | "0": { 2056 | "name": "meta.brace.round.wasm" 2057 | } 2058 | }, 2059 | "patterns": [ 2060 | { 2061 | "include": "#extra" 2062 | }, 2063 | { 2064 | "include": "#funcType" 2065 | } 2066 | ] 2067 | } 2068 | ] 2069 | }, 2070 | "typeUse": { 2071 | "name": "meta.typeUse.wasm", 2072 | "begin": "\\btype\\b", 2073 | "beginCaptures": { 2074 | "0": { 2075 | "name": "storage.type.type.wasm" 2076 | } 2077 | }, 2078 | "end": "(?=\\))", 2079 | "patterns": [ 2080 | { 2081 | "name": "entity.name.type.alias.wasm", 2082 | "match": "(?:(?!0x)[0-9]+(?:_?[0-9]+)*|0x[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*)|(?:\\$[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+)" 2083 | } 2084 | ] 2085 | }, 2086 | "valueType": { 2087 | "name": "meta.valueType.wasm storage.valueType.wasm", 2088 | "match": "[fi](?:32|64)" 2089 | } 2090 | } 2091 | } -------------------------------------------------------------------------------- /contributes/languages/wast.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoCloseBefore": ") \n\t", 3 | "autoClosingPairs": [ 4 | { "open": "(;", "close": ";", "notIn": ["string"] }, 5 | { "open": "(", "close": ")", "notIn": ["comment", "string"] }, 6 | { "open": "\"", "close": "\"", "notIn": ["string"] } 7 | ], 8 | "brackets": [["(", ")"]], 9 | "comments": { 10 | "lineComment": ";;", 11 | "blockComment": ["(;", ";)"] 12 | }, 13 | "surroundingPairs": [ 14 | ["(", ")"], 15 | ["\"", "\""] 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /contributes/languages/wat.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoCloseBefore": ") \n\t", 3 | "autoClosingPairs": [ 4 | { "open": "(;", "close": ";", "notIn": ["string"] }, 5 | { "open": "(", "close": ")", "notIn": ["comment", "string"] }, 6 | { "open": "\"", "close": "\"", "notIn": ["string"] } 7 | ], 8 | "brackets": [["(", ")"]], 9 | "comments": { 10 | "lineComment": ";;", 11 | "blockComment": ["(;", ";)"] 12 | }, 13 | "surroundingPairs": [ 14 | ["(", ")"], 15 | ["\"", "\""] 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-wasm", 3 | "description": "Visual Studio Code client for the WebAssembly language server", 4 | "version": "0.0.1", 5 | "license": "Apache-2.0 WITH LLVM-exception", 6 | "author": { 7 | "name": "silvanshade", 8 | "email": "silvanshade@users.noreply.github.com", 9 | "url": "https://github.com/silvanshade" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/freebroccolo/vscode-reasonml.git" 14 | }, 15 | "displayName": "vscode-wasm", 16 | "publisher": "silvanshade", 17 | "engines": { 18 | "vscode": "^1.51.1" 19 | }, 20 | "categories": [ 21 | "Programming Languages" 22 | ], 23 | "scripts": { 24 | "build": "tsc -p . && node script/syntax.js", 25 | "format": "prettier --write '**/*.{js,json,ts,tsx,yml,yaml}'", 26 | "lint": "eslint 'src/**/*.{js,ts,tsx}' && prettier --check '**/*.{js,json,ts,tsx,yml,yaml}'", 27 | "watch": "tsc -watch -p ." 28 | }, 29 | "dependencies": { 30 | "vscode-languageclient": "^8.0.0" 31 | }, 32 | "devDependencies": { 33 | "@types/node": "^17.0.0", 34 | "@types/vscode": "^1.53.0", 35 | "@typescript-eslint/eslint-plugin": "^5.26.0", 36 | "@typescript-eslint/parser": "^5.26.0", 37 | "eslint": "^8.16.0", 38 | "eslint-config-prettier": "^8.5.0", 39 | "eslint-plugin-prettier": "^4.0.0", 40 | "prettier": "^2.2.1", 41 | "typescript": "^4.1.5", 42 | "vscode-test": "^1.5.0" 43 | }, 44 | "main": "./out/extension", 45 | "activationEvents": [ 46 | "onLanguage:wasm.wat", 47 | "onLanguage:wasm.wast", 48 | "onLanguage:wasm.wit", 49 | "onLanguage:wasm.witx", 50 | "workspaceContains:**/*.wat", 51 | "workspaceContains:**/*.wast", 52 | "workspaceContains:**/*.wit", 53 | "workspaceContains:**/*.witx" 54 | ], 55 | "contributes": { 56 | "grammars": [ 57 | { 58 | "language": "wasm.wat", 59 | "scopeName": "source.wasm.wat", 60 | "path": "./contributes/grammars/wat.json" 61 | }, 62 | { 63 | "language": "wasm.wast", 64 | "scopeName": "source.wasm.wast", 65 | "path": "./contributes/grammars/wast.json" 66 | } 67 | ], 68 | "languages": [ 69 | { 70 | "id": "wasm.wat", 71 | "aliases": [ 72 | "WebAssembly Module" 73 | ], 74 | "extensions": [ 75 | ".wat" 76 | ], 77 | "configuration": "./contributes/languages/wat.json" 78 | }, 79 | { 80 | "id": "wasm.wast", 81 | "aliases": [ 82 | "WebAssembly Script" 83 | ], 84 | "extensions": [ 85 | ".wast" 86 | ], 87 | "configuration": "./contributes/languages/wast.json" 88 | } 89 | ] 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /script/syntax.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const languages = ["wat", "wast"]; 4 | 5 | function inPath(language) { 6 | return path.resolve(".", "out", "contributes", "grammars", language); 7 | } 8 | 9 | function outPath(language) { 10 | return path.resolve(".", "contributes", "grammars", `${language}.json`); 11 | } 12 | 13 | for (const language of languages) { 14 | const from = inPath(language); 15 | const into = outPath(language); 16 | const data = require(from); 17 | const json = JSON.stringify(data.default, null, 2); 18 | fs.writeFileSync(into, json); 19 | } 20 | -------------------------------------------------------------------------------- /src/client/index.ts: -------------------------------------------------------------------------------- 1 | import * as lspClient from "vscode-languageclient/node"; 2 | import * as vscode from "vscode"; 3 | 4 | export async function launch(): Promise { 5 | const run: lspClient.Executable = { 6 | command: "wasm-lsp", 7 | }; 8 | 9 | const debug: lspClient.Executable = { 10 | command: "wasm-lsp", 11 | options: { 12 | env: { 13 | RUST_BACKTRACE: "full", 14 | RUST_LOG: "info", 15 | ...process.env, 16 | }, 17 | }, 18 | }; 19 | 20 | const serverOptions: lspClient.ServerOptions = { debug, run }; 21 | const clientOptions: lspClient.LanguageClientOptions = { 22 | diagnosticCollectionName: "wasm-lsp", 23 | documentSelector: [ 24 | { language: "wasm.wat", scheme: "file" }, 25 | { language: "wasm.wat", scheme: "untitled" }, 26 | { language: "wasm.wast", scheme: "file" }, 27 | { language: "wasm.wast", scheme: "untitled" }, 28 | { language: "wasm.wit", scheme: "file" }, 29 | { language: "wasm.wit", scheme: "untitled" }, 30 | { language: "wasm.witx", scheme: "file" }, 31 | { language: "wasm.witx", scheme: "untitled" }, 32 | ], 33 | synchronize: { 34 | fileEvents: [ 35 | vscode.workspace.createFileSystemWatcher("**/*.wat"), 36 | vscode.workspace.createFileSystemWatcher("**/*.wast"), 37 | ], 38 | }, 39 | }; 40 | 41 | const languageClient = new lspClient.LanguageClient( 42 | "wasm-lsp", 43 | "WebAssembly Language Server", 44 | serverOptions, 45 | clientOptions, 46 | ); 47 | 48 | languageClient.registerProposedFeatures(); 49 | await languageClient.start(); 50 | return languageClient; 51 | } 52 | -------------------------------------------------------------------------------- /src/contributes/grammars/basis.ts: -------------------------------------------------------------------------------- 1 | import * as schema from "./schema"; 2 | 3 | export const Class = { 4 | alnum: "[:alnum:]", 5 | alpha: "[:alpha:]", 6 | ascii: "[:ascii:]", 7 | blank: "[:blank:]", 8 | cntrl: "[:cntrl:]", 9 | digit: "[:digit:]", 10 | graph: "[:graph:]", 11 | lower: "[:lower:]", 12 | print: "[:print:]", 13 | punct: "[:punct:]", 14 | space: "[:space:]", 15 | upper: "[:upper:]", 16 | word: "[:word:]", 17 | xdigit: "[:xdigit:]", 18 | }; 19 | 20 | const sign = "[+-]"; 21 | 22 | const hexnum = "[0-9A-Fa-f]+(?:_?[0-9A-Fa-f]+)*"; 23 | 24 | const num = "[0-9]+(?:_?[0-9]+)*"; 25 | 26 | const float = `${num}(?:\\.(?:${num})?)?(?:[Ee](?:${sign})?${num})?`; 27 | 28 | const hexfloat = `0x${hexnum}(?:\\.(?:${hexnum})?)?(?:[Pp](?:${sign})?${num})?`; 29 | 30 | const fNmag = `${float}|${hexfloat}|\b(?:inf|nan|nan:0x${hexnum}\b)`; 31 | 32 | const fN = `(?:${sign})?${fNmag}`; 33 | 34 | const uN = `(?!0x)${num}|0x${hexnum}`; 35 | 36 | const sN = `${sign}${uN}`; 37 | 38 | const id = "[0-9A-Za-z!#$%&'*+-./:<=>?@\\^_'|~]+"; 39 | 40 | const identifier = `\\$${id}`; 41 | 42 | const index = `(?:${uN})|(?:${identifier})`; 43 | 44 | const valueType = "[fi](?:32|64)"; 45 | 46 | export function ref(f: (...args: T) => schema.Rule): string { 47 | return `#${f.name}`; 48 | } 49 | 50 | export function include(f: (...args: T) => schema.Rule): { include: string } { 51 | return { include: ref(f) }; 52 | } 53 | 54 | export const alt = (...rest: string[]): string => rest.join("|"); 55 | 56 | export const capture = (arg: string): string => `(${arg})`; 57 | 58 | export const complement = (...rest: string[]): string => `[^${rest.join("")}]`; 59 | 60 | export const group = (arg: string): string => `(?:${arg})`; 61 | 62 | export const lookAhead = (arg: string): string => `(?=${arg})`; 63 | 64 | export const lookBehind = (arg: string): string => `(?<=${arg})`; 65 | 66 | export const many = (arg: string): string => `${arg}*`; 67 | 68 | export const manyOne = (arg: string): string => `${arg}+`; 69 | 70 | export const negativeLookAhead = (arg: string): string => `(?!${arg})`; 71 | 72 | export const negativeLookBehind = (arg: string): string => `(? `(?:${arg})?`; 75 | 76 | export const seq = (...rest: string[]): string => rest.join(""); 77 | 78 | export const set = (...rest: string[]): string => `[${rest.join("")}]`; 79 | 80 | export const words = (arg: string): string => `\\b${arg}\\b`; 81 | 82 | export const ops = (arg: string): string => { 83 | const operatorTokens: string[] = ["\\."]; 84 | return seq(negativeLookBehind(set(...operatorTokens)), arg, negativeLookAhead(set(...operatorTokens))); 85 | }; 86 | 87 | export const lastOps = (...rest: string[]): string => { 88 | const operatorTokens: string[] = ["\\."]; 89 | const result: string[] = []; 90 | for (const token of rest) { 91 | result.push(`[^${seq(...operatorTokens)}]${token}`, `^${token}`); 92 | } 93 | return group(seq(lookBehind(group(alt(...result))), negativeLookAhead(set(...operatorTokens)))); 94 | }; 95 | 96 | export const lastWords = (...rest: string[]): string => { 97 | const result: string[] = []; 98 | for (const token of rest) result.push(`[^${id}]${token}`, `^${token}`); 99 | return group(seq(lookBehind(group(alt(...result))), negativeLookAhead(`${id}`))); 100 | }; 101 | 102 | const instrTypeInt: string = seq("i", group(alt("32", "64"))); 103 | 104 | const instrTypeInt32: string = seq("i", "32"); 105 | 106 | const instrTypeInt64: string = seq("i", "64"); 107 | 108 | const instrTypeFloat: string = seq("f", group(alt("32", "64"))); 109 | 110 | const instrTypeFloat32: string = seq("f", "32"); 111 | 112 | const instrTypeFloat64: string = seq("f", "64"); 113 | 114 | const instrType: string = group(alt(instrTypeInt, instrTypeFloat)); 115 | 116 | const instrEnd: string = negativeLookAhead(alt(set(Class.space), "$", index)); 117 | 118 | export const Token = { 119 | ASSERT_EXHAUSTION: "assert_exhaustion", 120 | ASSERT_INVALID: "assert_invalid", 121 | ASSERT_MALFORMED: "assert_malformed", 122 | ASSERT_RETURN: "assert_return", 123 | ASSERT_TRAP: "assert_trap", 124 | ASSERT_UNLINKABLE: "assert_unlinkable", 125 | BINARY: "binary", 126 | BLOCK: "block", 127 | BR: "br", 128 | BR_IF: "br_if", 129 | BR_TABLE: "br_table", 130 | CALL: "call", 131 | CALL_INDIRECT: "call_indirect", 132 | CONST: "const", 133 | DATA: "data", 134 | DROP: "drop", 135 | ELEM: "elem", 136 | ELSE: "else", 137 | END: "end", 138 | EXPORT: "export", 139 | FULL_STOP: "\\.", 140 | FUNC: "func", 141 | FUNCREF: "funcref", 142 | GET: "get", 143 | GLOBAL: "global(?!\\.)", 144 | GLOBAL_GET: "global\\.get", 145 | GLOBAL_SET: "global\\.set", 146 | IF: "if", 147 | IMPORT: "import", 148 | INPUT: "input", 149 | INVOKE: "invoke", 150 | LEFT_PARENTHESIS: "\\(", 151 | LOCAL: "local(?!\\.)", 152 | LOCAL_GET: "local\\.get", 153 | LOCAL_SET: "local\\.set", 154 | LOCAL_TEE: "local\\.tee", 155 | LOOP: "loop", 156 | MEMORY: "memory(?!\\.)", 157 | MEMORY_GROW: "memory\\.grow", 158 | MEMORY_SIZE: "memory\\.size", 159 | MODULE: "module", 160 | MUT: "mut", 161 | NOP: "nop", 162 | OFFSET: "offset", 163 | OUTPUT: "output", 164 | PARAM: "param", 165 | QUOTE: "quote", 166 | REGISTER: "register", 167 | RESULT: "result", 168 | RETURN: "return", 169 | RIGHT_PARENTHESIS: "\\)", 170 | SCRIPT: "script", 171 | SELECT: "select", 172 | START: "start", 173 | TABLE: "table", 174 | THEN: "then", 175 | TYPE: "type", 176 | UNREACHABLE: "unreachable", 177 | escape: "\\\\([0-9A-Fa-f]{2}|u\\{[0-9A-Fa-f]+\\}|[\\\\'\\\\\"ntr]|$)", 178 | float, 179 | fN, 180 | hexfloat, 181 | hexnum, 182 | id, 183 | identifier, 184 | index, 185 | instrEnd, 186 | instrType, 187 | instrTypeFloat, 188 | instrTypeFloat32, 189 | instrTypeFloat64, 190 | instrTypeInt, 191 | instrTypeInt32, 192 | instrTypeInt64, 193 | num, 194 | sign, 195 | sN, 196 | uN, 197 | valueType, 198 | }; 199 | 200 | export class Scope {} 201 | 202 | export interface Render { 203 | render(): schema.Grammar; 204 | } 205 | -------------------------------------------------------------------------------- /src/contributes/grammars/schema.ts: -------------------------------------------------------------------------------- 1 | export type Patterns = Array; 2 | 3 | export interface Grammar { 4 | name: string; 5 | scopeName: string; 6 | fileTypes: string[]; 7 | patterns: Patterns; 8 | repository: Repository; 9 | } 10 | 11 | export interface MatchScopes { 12 | [key: string]: RuleSimple; 13 | } 14 | 15 | export type Rule = RuleSimple | RuleCapturing | RuleDelimited | RuleReference; 16 | 17 | export interface RuleCapturing { 18 | match: string; 19 | name?: string; 20 | captures?: MatchScopes; 21 | patterns?: Patterns; 22 | } 23 | 24 | export interface RuleDelimited { 25 | begin: string; 26 | end: string; 27 | applyEndPatternLast?: boolean; 28 | name?: string; 29 | contentName?: string; 30 | beginCaptures?: MatchScopes; 31 | endCaptures?: MatchScopes; 32 | patterns?: Patterns; 33 | } 34 | 35 | export interface RuleReference { 36 | include: string; 37 | } 38 | 39 | export type RuleSimple = 40 | | { 41 | name: string; 42 | patterns?: Patterns; 43 | } 44 | | { 45 | name?: string; 46 | patterns: Patterns; 47 | }; 48 | 49 | export interface Repository { 50 | [key: string]: Rule; 51 | } 52 | -------------------------------------------------------------------------------- /src/contributes/grammars/wast.ts: -------------------------------------------------------------------------------- 1 | /* eslint @typescript-eslint/unbound-method: "off" */ 2 | 3 | import * as basis from "./basis"; 4 | import * as schema from "./schema"; 5 | import { Wat } from "./wat"; 6 | 7 | const { Token, include, lookAhead, words } = basis; 8 | 9 | export class Wast extends Wat { 10 | constructor() { 11 | super(); 12 | return this; 13 | } 14 | 15 | public render(): schema.Grammar { 16 | return { 17 | name: "WebAssembly Script", 18 | scopeName: "source.wasm.wast", 19 | fileTypes: [".wast"], 20 | patterns: [include(this.PARSE)], 21 | repository: { 22 | ...super.render().repository, 23 | PARSE: this.PARSE(), 24 | action: this.action(), 25 | actionGet: this.actionGet(), 26 | actionInvoke: this.actionInvoke(), 27 | assertExhaustion: this.assertExhaustion(), 28 | assertInvalid: this.assertInvalid(), 29 | assertion: this.assertion(), 30 | assertMalformed: this.assertMalformed(), 31 | assertReturn: this.assertReturn(), 32 | assertTrap: this.assertTrap(), 33 | assertUnlinkable: this.assertUnlinkable(), 34 | command: this.command(), 35 | exprPlainConst: this.exprPlainConst(), 36 | meta: this.meta(), 37 | metaInput: this.metaInput(), 38 | metaOutput: this.metaOutput(), 39 | metaScript: this.metaScript(), 40 | register: this.register(), 41 | result: this.result(), 42 | scriptModule: this.scriptModule(), 43 | }, 44 | }; 45 | } 46 | 47 | PARSE(): schema.Rule { 48 | return { 49 | patterns: [ 50 | include(this.extra), 51 | { 52 | begin: Token.LEFT_PARENTHESIS, 53 | beginCaptures: { 54 | 0: { name: "meta.brace.round.wasm" }, 55 | }, 56 | end: Token.RIGHT_PARENTHESIS, 57 | endCaptures: { 58 | 0: { name: "meta.brace.round.wasm" }, 59 | }, 60 | patterns: [include(this.extra), include(this.command), include(this.moduleField)], 61 | }, 62 | ], 63 | }; 64 | } 65 | 66 | action(): schema.Rule { 67 | return { 68 | patterns: [include(this.actionInvoke), include(this.actionGet)], 69 | }; 70 | } 71 | 72 | actionGet(): schema.Rule { 73 | return { 74 | name: "meta.action.get.wasm", 75 | begin: words(Token.GET), 76 | beginCaptures: { 77 | 0: { name: "keyword.control.get.wasm" }, 78 | }, 79 | end: lookAhead(Token.RIGHT_PARENTHESIS), 80 | patterns: [ 81 | { 82 | name: "variable.other.wasm", 83 | match: Token.identifier, 84 | }, 85 | { 86 | name: "variable.other.readwrite.alias.wasm", 87 | begin: '"', 88 | end: '"', 89 | patterns: [ 90 | { 91 | match: Token.escape, 92 | }, 93 | ], 94 | }, 95 | ], 96 | }; 97 | } 98 | 99 | actionInvoke(): schema.Rule { 100 | return { 101 | name: "meta.action.invoke.wasm", 102 | begin: words(Token.INVOKE), 103 | beginCaptures: { 104 | 0: { name: "keyword.control.invoke.wasm" }, 105 | }, 106 | end: lookAhead(Token.RIGHT_PARENTHESIS), 107 | patterns: [ 108 | { 109 | name: "variable.other.wasm", 110 | match: Token.identifier, 111 | }, 112 | { 113 | name: "variable.other.readwrite.alias.wasm", 114 | begin: '"', 115 | end: '"', 116 | patterns: [ 117 | { 118 | match: Token.escape, 119 | }, 120 | ], 121 | }, 122 | { 123 | begin: Token.LEFT_PARENTHESIS, 124 | beginCaptures: { 125 | 0: { name: "meta.brace.round.wasm" }, 126 | }, 127 | end: Token.RIGHT_PARENTHESIS, 128 | endCaptures: { 129 | 0: { name: "meta.brace.round.wasm" }, 130 | }, 131 | patterns: [include(this.exprPlainConst)], 132 | }, 133 | ], 134 | }; 135 | } 136 | 137 | assertion(): schema.Rule { 138 | return { 139 | patterns: [ 140 | include(this.assertExhaustion), 141 | include(this.assertInvalid), 142 | include(this.assertMalformed), 143 | include(this.assertReturn), 144 | include(this.assertTrap), 145 | include(this.assertUnlinkable), 146 | ], 147 | }; 148 | } 149 | 150 | assertExhaustion(): schema.Rule { 151 | return { 152 | name: "meta.assert.exhaustion.wasm", 153 | begin: words(Token.ASSERT_EXHAUSTION), 154 | beginCaptures: { 155 | 0: { name: "keyword.control.assert.exhaustion.wasm" }, 156 | }, 157 | end: lookAhead(Token.RIGHT_PARENTHESIS), 158 | patterns: [ 159 | include(this.extra), 160 | { 161 | begin: Token.LEFT_PARENTHESIS, 162 | beginCaptures: { 163 | 0: { name: "meta.brace.round.wasm" }, 164 | }, 165 | end: Token.RIGHT_PARENTHESIS, 166 | endCaptures: { 167 | 0: { name: "meta.brace.round.wasm" }, 168 | }, 169 | patterns: [include(this.action)], 170 | }, 171 | include(this.string), 172 | ], 173 | }; 174 | } 175 | 176 | assertInvalid(): schema.Rule { 177 | return { 178 | name: "meta.assert.invalid.wasm", 179 | begin: words(Token.ASSERT_INVALID), 180 | beginCaptures: { 181 | 0: { name: "keyword.control.assert.invalid.wasm" }, 182 | }, 183 | end: lookAhead(Token.RIGHT_PARENTHESIS), 184 | patterns: [ 185 | include(this.extra), 186 | { 187 | begin: Token.LEFT_PARENTHESIS, 188 | beginCaptures: { 189 | 0: { name: "meta.brace.round.wasm" }, 190 | }, 191 | end: Token.RIGHT_PARENTHESIS, 192 | endCaptures: { 193 | 0: { name: "meta.brace.round.wasm" }, 194 | }, 195 | patterns: [include(this.scriptModule)], 196 | }, 197 | include(this.string), 198 | ], 199 | }; 200 | } 201 | 202 | assertMalformed(): schema.Rule { 203 | return { 204 | name: "meta.assert.malformed.wasm", 205 | begin: words(Token.ASSERT_MALFORMED), 206 | beginCaptures: { 207 | 0: { name: "keyword.control.assert.malformed.wasm" }, 208 | }, 209 | end: lookAhead(Token.RIGHT_PARENTHESIS), 210 | patterns: [ 211 | include(this.extra), 212 | { 213 | begin: Token.LEFT_PARENTHESIS, 214 | beginCaptures: { 215 | 0: { name: "meta.brace.round.wasm" }, 216 | }, 217 | end: Token.RIGHT_PARENTHESIS, 218 | endCaptures: { 219 | 0: { name: "meta.brace.round.wasm" }, 220 | }, 221 | patterns: [include(this.scriptModule)], 222 | }, 223 | include(this.string), 224 | ], 225 | }; 226 | } 227 | 228 | assertReturn(): schema.Rule { 229 | return { 230 | name: "meta.assert.return.wasm", 231 | begin: words(Token.ASSERT_RETURN), 232 | beginCaptures: { 233 | 0: { name: "keyword.control.assert.return.wasm" }, 234 | }, 235 | end: lookAhead(Token.RIGHT_PARENTHESIS), 236 | patterns: [ 237 | include(this.extra), 238 | { 239 | begin: Token.LEFT_PARENTHESIS, 240 | beginCaptures: { 241 | 0: { name: "meta.brace.round.wasm" }, 242 | }, 243 | end: Token.RIGHT_PARENTHESIS, 244 | endCaptures: { 245 | 0: { name: "meta.brace.round.wasm" }, 246 | }, 247 | patterns: [include(this.action), include(this.result)], 248 | }, 249 | ], 250 | }; 251 | } 252 | 253 | assertTrap(): schema.Rule { 254 | return { 255 | name: "meta.assert.trap.wasm", 256 | begin: words(Token.ASSERT_TRAP), 257 | beginCaptures: { 258 | 0: { name: "keyword.control.assert.trap.wasm" }, 259 | }, 260 | end: lookAhead(Token.RIGHT_PARENTHESIS), 261 | patterns: [ 262 | include(this.extra), 263 | { 264 | begin: Token.LEFT_PARENTHESIS, 265 | beginCaptures: { 266 | 0: { name: "meta.brace.round.wasm" }, 267 | }, 268 | end: Token.RIGHT_PARENTHESIS, 269 | endCaptures: { 270 | 0: { name: "meta.brace.round.wasm" }, 271 | }, 272 | patterns: [include(this.action), include(this.scriptModule)], 273 | }, 274 | include(this.string), 275 | ], 276 | }; 277 | } 278 | 279 | assertUnlinkable(): schema.Rule { 280 | return { 281 | name: "meta.assert.unlinkable.wasm", 282 | begin: words(Token.ASSERT_UNLINKABLE), 283 | beginCaptures: { 284 | 0: { name: "keyword.control.assert.unlinkable.wasm" }, 285 | }, 286 | end: lookAhead(Token.RIGHT_PARENTHESIS), 287 | patterns: [ 288 | include(this.extra), 289 | { 290 | begin: Token.LEFT_PARENTHESIS, 291 | beginCaptures: { 292 | 0: { name: "meta.brace.round.wasm" }, 293 | }, 294 | end: Token.RIGHT_PARENTHESIS, 295 | endCaptures: { 296 | 0: { name: "meta.brace.round.wasm" }, 297 | }, 298 | patterns: [include(this.scriptModule)], 299 | }, 300 | include(this.string), 301 | ], 302 | }; 303 | } 304 | 305 | command(): schema.Rule { 306 | return { 307 | patterns: [ 308 | include(this.action), 309 | include(this.assertion), 310 | include(this.meta), 311 | include(this.register), 312 | include(this.scriptModule), 313 | ], 314 | }; 315 | } 316 | 317 | exprPlainConst(): schema.Rule { 318 | return { 319 | patterns: [include(this.instrPlainConst)], 320 | }; 321 | } 322 | 323 | meta(): schema.Rule { 324 | return { 325 | patterns: [include(this.metaScript), include(this.metaInput), include(this.metaOutput)], 326 | }; 327 | } 328 | 329 | metaScript(): schema.Rule { 330 | return { 331 | name: "meta.meta.script.wasm", 332 | begin: words(Token.SCRIPT), 333 | beginCaptures: { 334 | 0: { name: "keyword.control.meta.script.wasm" }, 335 | }, 336 | end: lookAhead(Token.RIGHT_PARENTHESIS), 337 | patterns: [ 338 | { 339 | name: "variable.other.wasm", 340 | match: Token.identifier, 341 | }, 342 | include(this.command), 343 | ], 344 | }; 345 | } 346 | 347 | metaInput(): schema.Rule { 348 | return { 349 | name: "meta.meta.input.wasm", 350 | begin: words(Token.INPUT), 351 | beginCaptures: { 352 | 0: { name: "keyword.control.meta.input.wasm" }, 353 | }, 354 | end: lookAhead(Token.RIGHT_PARENTHESIS), 355 | patterns: [ 356 | { 357 | name: "variable.other.wasm", 358 | match: Token.identifier, 359 | }, 360 | include(this.string), 361 | ], 362 | }; 363 | } 364 | 365 | metaOutput(): schema.Rule { 366 | return { 367 | name: "meta.meta.output.wasm", 368 | begin: words(Token.OUTPUT), 369 | beginCaptures: { 370 | 0: { name: "keyword.control.meta.output.wasm" }, 371 | }, 372 | end: lookAhead(Token.RIGHT_PARENTHESIS), 373 | patterns: [ 374 | { 375 | name: "variable.other.wasm", 376 | match: Token.identifier, 377 | }, 378 | include(this.string), 379 | ], 380 | }; 381 | } 382 | 383 | register(): schema.Rule { 384 | return { 385 | name: "meta.register.wasm", 386 | begin: words(Token.REGISTER), 387 | beginCaptures: { 388 | 0: { name: "keyword.control.meta.output.wasm" }, 389 | }, 390 | end: lookAhead(Token.RIGHT_PARENTHESIS), 391 | patterns: [ 392 | include(this.name), 393 | { 394 | name: "variable.other.wasm", 395 | match: Token.identifier, 396 | }, 397 | ], 398 | }; 399 | } 400 | 401 | result(): schema.Rule { 402 | return { 403 | patterns: [include(this.exprPlainConst)], 404 | }; 405 | } 406 | 407 | scriptModule(): schema.Rule { 408 | return { 409 | patterns: [ 410 | { 411 | begin: words(Token.MODULE), 412 | beginCaptures: { 413 | 0: { name: "storage.type.module.wasm" }, 414 | }, 415 | end: lookAhead(Token.RIGHT_PARENTHESIS), 416 | patterns: [ 417 | include(this.extra), 418 | { 419 | begin: `\\$${Token.id}`, 420 | beginCaptures: { 421 | 0: { name: "entity.name.type.module.wasm" }, 422 | }, 423 | end: lookAhead(Token.RIGHT_PARENTHESIS), 424 | patterns: [ 425 | include(this.extra), 426 | { 427 | begin: Token.LEFT_PARENTHESIS, 428 | beginCaptures: { 429 | 0: { name: "meta.brace.round.wasm" }, 430 | }, 431 | end: Token.RIGHT_PARENTHESIS, 432 | endCaptures: { 433 | 0: { name: "meta.brace.round.wasm" }, 434 | }, 435 | patterns: [include(this.moduleField)], 436 | }, 437 | ], 438 | }, 439 | { 440 | begin: words(Token.BINARY), 441 | beginCaptures: { 442 | 0: { name: "storage.modifier.module.binary.wasm" }, 443 | }, 444 | end: lookAhead(Token.RIGHT_PARENTHESIS), 445 | patterns: [include(this.extra), include(this.string)], 446 | }, 447 | { 448 | begin: words(Token.QUOTE), 449 | beginCaptures: { 450 | 0: { name: "storage.modifier.module.quote.wasm" }, 451 | }, 452 | end: lookAhead(Token.RIGHT_PARENTHESIS), 453 | patterns: [include(this.extra), include(this.string)], 454 | }, 455 | { 456 | begin: Token.LEFT_PARENTHESIS, 457 | beginCaptures: { 458 | 0: { name: "meta.brace.round.wasm" }, 459 | }, 460 | end: Token.RIGHT_PARENTHESIS, 461 | endCaptures: { 462 | 0: { name: "meta.brace.round.wasm" }, 463 | }, 464 | patterns: [include(this.moduleField)], 465 | }, 466 | ], 467 | }, 468 | ], 469 | }; 470 | } 471 | } 472 | 473 | export default new Wast().render(); 474 | -------------------------------------------------------------------------------- /src/contributes/grammars/wat.ts: -------------------------------------------------------------------------------- 1 | /* eslint @typescript-eslint/unbound-method: "off" */ 2 | 3 | // TODO: 4 | // * highlight rest of call_indirect (e.g., "param", "result", "type", etc.) 5 | // * highlight "param" 6 | // * fix highlighting for func fields (see conversions.wast) 7 | // * fix highlighting for export fields (memory, table, etc.) 8 | // * fix highlighting for global fields 9 | 10 | import * as basis from "./basis"; 11 | import * as schema from "./schema"; 12 | 13 | const { 14 | Class, 15 | Token, 16 | alt, 17 | capture, 18 | group, 19 | include, 20 | lastWords, 21 | lookAhead, 22 | lookBehind, 23 | manyOne, 24 | negativeLookAhead, 25 | ops, 26 | opt, 27 | seq, 28 | set, 29 | words, 30 | } = basis; 31 | 32 | export class Wat implements basis.Render { 33 | constructor() { 34 | return this; 35 | } 36 | 37 | public render(): schema.Grammar { 38 | return { 39 | name: "WebAssembly Module", 40 | scopeName: "source.wasm.wat", 41 | fileTypes: [".wat"], 42 | patterns: [include(this.PARSE)], 43 | repository: { 44 | PARSE: this.PARSE(), 45 | alignValue: this.alignValue(), 46 | annotation: this.annotation(), 47 | annotationParens: this.annotationParens(), 48 | annotationPart: this.annotationPart(), 49 | blockBlock: this.blockBlock(), 50 | blockComment: this.blockComment(), 51 | blockIf: this.blockIf(), 52 | blockLoop: this.blockLoop(), 53 | comment: this.comment(), 54 | elemType: this.elemType(), 55 | exportDesc: this.exportDesc(), 56 | exportDescFunc: this.exportDescFunc(), 57 | exportDescGlobal: this.exportDescGlobal(), 58 | exportDescMemory: this.exportDescMemory(), 59 | exportDescTable: this.exportDescTable(), 60 | expr: this.expr(), 61 | exprBlock: this.exprBlock(), 62 | exprCall: this.exprCall(), 63 | exprIf: this.exprIf(), 64 | exprLoop: this.exprLoop(), 65 | exprPlain: this.exprPlain(), 66 | extra: this.extra(), 67 | funcLocals: this.funcLocals(), 68 | funcType: this.funcType(), 69 | funcTypeParams: this.funcTypeParams(), 70 | funcTypeResults: this.funcTypeResults(), 71 | globalType: this.globalType(), 72 | globalTypeImm: this.globalTypeImm(), 73 | globalTypeMut: this.globalTypeMut(), 74 | importDesc: this.importDesc(), 75 | importDescFuncType: this.importDescFuncType(), 76 | importDescGlobalType: this.importDescGlobalType(), 77 | importDescMemoryType: this.importDescMemoryType(), 78 | importDescTableType: this.importDescTableType(), 79 | inlineExport: this.inlineExport(), 80 | inlineImport: this.inlineImport(), 81 | inlineImportNames: this.inlineImportNames(), 82 | instr: this.instr(), 83 | instrBlock: this.instrBlock(), 84 | instrCall: this.instrCall(), 85 | instrList: this.instrList(), 86 | instrPlain: this.instrPlain(), 87 | instrPlainBinary: this.instrPlainBinary(), 88 | instrPlainBr: this.instrPlainBr(), 89 | instrPlainBrIf: this.instrPlainBrIf(), 90 | instrPlainBrTable: this.instrPlainBrTable(), 91 | instrPlainCall: this.instrPlainCall(), 92 | instrPlainCompare: this.instrPlainCompare(), 93 | instrPlainConvert: this.instrPlainConvert(), 94 | instrPlainConst: this.instrPlainConst(), 95 | instrPlainDrop: this.instrPlainDrop(), 96 | instrPlainGlobalGet: this.instrPlainGlobalGet(), 97 | instrPlainGlobalSet: this.instrPlainGlobalSet(), 98 | instrPlainLoad: this.instrPlainLoad(), 99 | instrPlainLocalGet: this.instrPlainLocalGet(), 100 | instrPlainLocalSet: this.instrPlainLocalSet(), 101 | instrPlainLocalTee: this.instrPlainLocalTee(), 102 | instrPlainMemorySize: this.instrPlainMemorySize(), 103 | instrPlainMemoryGrow: this.instrPlainMemoryGrow(), 104 | instrPlainNop: this.instrPlainNop(), 105 | instrPlainReturn: this.instrPlainReturn(), 106 | instrPlainSelect: this.instrPlainSelect(), 107 | instrPlainStore: this.instrPlainStore(), 108 | instrPlainTest: this.instrPlainTest(), 109 | instrPlainUnary: this.instrPlainUnary(), 110 | instrPlainUnreachable: this.instrPlainUnreachable(), 111 | limits: this.limits(), 112 | lineComment: this.lineComment(), 113 | memoryFieldsData: this.memoryFieldsData(), 114 | memoryFieldsType: this.memoryFieldsType(), 115 | memoryType: this.memoryType(), 116 | module: this.module(), 117 | moduleField: this.moduleField(), 118 | moduleFieldData: this.moduleFieldData(), 119 | moduleFieldElem: this.moduleFieldElem(), 120 | moduleFieldExport: this.moduleFieldExport(), 121 | moduleFieldFunc: this.moduleFieldFunc(), 122 | moduleFieldGlobal: this.moduleFieldGlobal(), 123 | moduleFieldImport: this.moduleFieldImport(), 124 | moduleFieldMemory: this.moduleFieldMemory(), 125 | moduleFieldStart: this.moduleFieldStart(), 126 | moduleFieldTable: this.moduleFieldTable(), 127 | moduleFieldType: this.moduleFieldType(), 128 | name: this.name(), 129 | offset: this.offset(), 130 | offsetConstExpr: this.offsetConstExpr(), 131 | offsetExpr: this.offsetExpr(), 132 | offsetValue: this.offsetValue(), 133 | string: this.string(), 134 | stringCharacterEscape: this.stringCharacterEscape(), 135 | tableFieldsElem: this.tableFieldsElem(), 136 | tableFieldsType: this.tableFieldsType(), 137 | tableType: this.tableType(), 138 | typeField: this.typeField(), 139 | typeUse: this.typeUse(), 140 | valueType: this.valueType(), 141 | }, 142 | }; 143 | } 144 | 145 | PARSE(): schema.Rule { 146 | return { 147 | name: "meta.PARSE.wasm", 148 | patterns: [ 149 | include(this.extra), 150 | { 151 | begin: Token.LEFT_PARENTHESIS, 152 | beginCaptures: { 153 | 0: { name: "meta.brace.round.wasm" }, 154 | }, 155 | end: Token.RIGHT_PARENTHESIS, 156 | endCaptures: { 157 | 0: { name: "meta.brace.round.wasm" }, 158 | }, 159 | patterns: [include(this.extra), include(this.module), include(this.moduleField)], 160 | }, 161 | ], 162 | }; 163 | } 164 | 165 | alignValue(): schema.Rule { 166 | return { 167 | match: seq(manyOne(set(Class.space)), capture(words(seq("align=", group(alt(Token.num, `0x${Token.hexnum}`)))))), 168 | captures: { 169 | 1: { name: "storage.modifier.wasm" }, 170 | }, 171 | }; 172 | } 173 | 174 | annotation(): schema.Rule { 175 | return { 176 | name: "meta.annotation.wasm", 177 | begin: seq(Token.LEFT_PARENTHESIS, lookAhead("@")), 178 | beginCaptures: { 179 | 0: { name: "meta.brace.round.annotation.wasm punctuation.definition.tag" }, 180 | }, 181 | end: Token.RIGHT_PARENTHESIS, 182 | endCaptures: { 183 | 0: { name: "meta.brace.round.annotation.wasm punctuation.definition.tag" }, 184 | }, 185 | patterns: [ 186 | { 187 | begin: "@", 188 | beginCaptures: { 189 | 0: { name: "meta.annotation.name.wasm punctuation.definition.tag" }, 190 | }, 191 | end: lookAhead(Token.RIGHT_PARENTHESIS), 192 | endCaptures: { 193 | 0: { name: "meta.brace.round.annotation.wasm" }, 194 | }, 195 | patterns: [ 196 | { 197 | begin: Token.id, 198 | beginCaptures: { 199 | 0: { name: "meta.annotation.wasm constant.regexp" }, 200 | }, 201 | end: lookAhead(Token.RIGHT_PARENTHESIS), 202 | contentName: "comment.wasm", 203 | patterns: [include(this.annotationPart)], 204 | }, 205 | ], 206 | }, 207 | ], 208 | }; 209 | } 210 | 211 | annotationParens(): schema.Rule { 212 | return { 213 | name: "meta.annotationParens.wasm", 214 | begin: Token.LEFT_PARENTHESIS, 215 | end: Token.RIGHT_PARENTHESIS, 216 | patterns: [include(this.annotationPart)], 217 | }; 218 | } 219 | 220 | annotationPart(): schema.Rule { 221 | return { 222 | name: "meta.annotationPart.wasm", 223 | patterns: [ 224 | include(this.comment), 225 | include(this.annotationParens), 226 | // include(this.uN), 227 | // include(this.sN), 228 | // include(this.fN), 229 | { 230 | match: Token.id, 231 | }, 232 | { 233 | begin: '"', 234 | end: '(")|((?:[^\\\\\\n])$)', 235 | patterns: [ 236 | { 237 | name: "constant.character.escape.wasm", 238 | }, 239 | ], 240 | }, 241 | ], 242 | }; 243 | } 244 | 245 | blockBlock(): schema.Rule { 246 | // TODO: parse trailing optional identifier 247 | return { 248 | name: "meta.blockBlock.wasm", 249 | begin: words(Token.BLOCK), 250 | beginCaptures: { 251 | 0: { name: "keyword.control.wasm" }, 252 | }, 253 | end: words(Token.END), 254 | endCaptures: { 255 | 0: { name: "keyword.control.wasm" }, 256 | }, 257 | patterns: [ 258 | include(this.extra), 259 | { 260 | name: "variable.other.wasm", 261 | match: Token.identifier, 262 | }, 263 | include(this.typeUse), 264 | include(this.funcTypeParams), 265 | include(this.funcTypeResults), 266 | include(this.instrList), 267 | ], 268 | }; 269 | } 270 | 271 | blockIf(): schema.Rule { 272 | // TODO: parse trailing optional identifier 273 | // TODO: parse branches 274 | return { 275 | name: "meta.blockIf.wasm", 276 | begin: words(Token.IF), 277 | beginCaptures: { 278 | 0: { name: "keyword.control.wasm" }, 279 | }, 280 | end: words(Token.END), 281 | endCaptures: { 282 | 0: { name: "keyword.control.wasm" }, 283 | }, 284 | patterns: [ 285 | include(this.extra), 286 | { 287 | name: "variable.other.wasm", 288 | match: Token.identifier, 289 | }, 290 | include(this.typeUse), 291 | include(this.funcTypeParams), 292 | include(this.funcTypeResults), 293 | include(this.instrList), 294 | ], 295 | }; 296 | } 297 | 298 | blockLoop(): schema.Rule { 299 | // TODO: parse trailing optional identifier 300 | return { 301 | name: "meta.blockLoop.wasm", 302 | begin: words(Token.LOOP), 303 | beginCaptures: { 304 | 0: { name: "keyword.control.wasm" }, 305 | }, 306 | end: words(Token.END), 307 | endCaptures: { 308 | 0: { name: "keyword.control.wasm" }, 309 | }, 310 | patterns: [ 311 | include(this.extra), 312 | { 313 | name: "variable.other.wasm", 314 | match: Token.identifier, 315 | }, 316 | include(this.typeUse), 317 | include(this.funcTypeParams), 318 | include(this.funcTypeResults), 319 | include(this.instrList), 320 | ], 321 | }; 322 | } 323 | 324 | blockComment(): schema.Rule { 325 | return { 326 | name: "meta.blockComment.wasm comment.block.wasm", 327 | begin: capture("\\(;"), 328 | beginCaptures: { 329 | 1: { name: "punctuation.definition.comment.wasm" }, 330 | }, 331 | end: capture(";\\)"), 332 | endCaptures: { 333 | 1: { name: "punctuation.definition.comment.wasm" }, 334 | }, 335 | patterns: [include(this.blockComment)], 336 | }; 337 | } 338 | 339 | comment(): schema.Rule { 340 | return { 341 | name: "meta.comment.wasm", 342 | patterns: [include(this.lineComment), include(this.blockComment)], 343 | }; 344 | } 345 | 346 | elemType(): schema.Rule { 347 | return { 348 | name: "meta.elemType.wasm storage.type.wasm", 349 | match: words(Token.FUNCREF), 350 | }; 351 | } 352 | 353 | exportDesc(): schema.Rule { 354 | return { 355 | name: "meta.exportDesc.wasm", 356 | patterns: [ 357 | include(this.exportDescFunc), 358 | include(this.exportDescTable), 359 | include(this.exportDescMemory), 360 | include(this.exportDescGlobal), 361 | ], 362 | }; 363 | } 364 | 365 | exportDescFunc(): schema.Rule { 366 | return { 367 | name: "meta.exportDescFunc.wasm", 368 | begin: words(Token.FUNC), 369 | beginCaptures: { 370 | 0: { name: "keyword.control.func.wasm" }, 371 | }, 372 | end: lookAhead(Token.RIGHT_PARENTHESIS), 373 | patterns: [{ match: Token.index }], 374 | }; 375 | } 376 | 377 | exportDescGlobal(): schema.Rule { 378 | return { 379 | name: "meta.exportDescGlobal.wasm", 380 | begin: words(Token.GLOBAL), 381 | beginCaptures: { 382 | 0: { name: "keyword.control.global.wasm" }, 383 | }, 384 | end: lookAhead(Token.RIGHT_PARENTHESIS), 385 | patterns: [{ match: Token.index }], 386 | }; 387 | } 388 | 389 | exportDescMemory(): schema.Rule { 390 | return { 391 | name: "meta.exportDescMemory.wasm", 392 | begin: words(Token.MEMORY), 393 | beginCaptures: { 394 | 0: { name: "keyword.control.memory.wasm" }, 395 | }, 396 | end: lookAhead(Token.RIGHT_PARENTHESIS), 397 | patterns: [{ match: Token.index }], 398 | }; 399 | } 400 | 401 | exportDescTable(): schema.Rule { 402 | return { 403 | name: "meta.exportDescTable.wasm", 404 | begin: words(Token.TABLE), 405 | beginCaptures: { 406 | 0: { name: "keyword.control.table.wasm" }, 407 | }, 408 | end: lookAhead(Token.RIGHT_PARENTHESIS), 409 | patterns: [{ match: Token.index }], 410 | }; 411 | } 412 | 413 | expr(): schema.Rule { 414 | return { 415 | name: "meta.expr.wasm", 416 | patterns: [ 417 | include(this.exprPlain), 418 | include(this.exprCall), 419 | include(this.exprBlock), 420 | include(this.exprLoop), 421 | include(this.exprIf), 422 | { 423 | // NOTE: should this be included here or alongside expr in the parent rule? 424 | begin: Token.LEFT_PARENTHESIS, 425 | beginCaptures: { 426 | 0: { name: "meta.brace.round.wasm" }, 427 | }, 428 | end: Token.RIGHT_PARENTHESIS, 429 | endCaptures: { 430 | 0: { name: "meta.brace.round.wasm" }, 431 | }, 432 | patterns: [include(this.expr)], 433 | }, 434 | ], 435 | }; 436 | } 437 | 438 | exprBlock(): schema.Rule { 439 | return { 440 | name: "meta.exprBlock.wasm", 441 | begin: words(Token.BLOCK), 442 | beginCaptures: { 443 | 0: { name: "keyword.control.wasm" }, 444 | }, 445 | end: lookAhead(Token.RIGHT_PARENTHESIS), 446 | patterns: [ 447 | include(this.extra), 448 | { 449 | name: "variable.other.wasm", 450 | match: Token.identifier, 451 | }, 452 | { 453 | begin: Token.LEFT_PARENTHESIS, 454 | beginCaptures: { 455 | 0: { name: "meta.brace.round.wasm" }, 456 | }, 457 | end: Token.RIGHT_PARENTHESIS, 458 | endCaptures: { 459 | 0: { name: "meta.brace.round.wasm" }, 460 | }, 461 | patterns: [ 462 | include(this.extra), 463 | include(this.typeUse), 464 | include(this.funcTypeParams), 465 | include(this.funcTypeResults), 466 | include(this.expr), 467 | ], 468 | }, 469 | include(this.instrList), 470 | ], 471 | }; 472 | } 473 | 474 | exprCall(): schema.Rule { 475 | return { 476 | name: "meta.exprCall.wasm", 477 | patterns: [ 478 | { 479 | name: "keyword.control.wasm", 480 | match: words(Token.CALL_INDIRECT), 481 | }, 482 | ], 483 | }; 484 | } 485 | 486 | exprIf(): schema.Rule { 487 | return { 488 | name: "meta.exprIf.wasm", 489 | patterns: [ 490 | { 491 | name: "keyword.control.wasm", 492 | match: words(Token.IF), 493 | }, 494 | // TODO: proper parsing of branches 495 | { 496 | name: "keyword.control.wasm", 497 | match: words(alt(Token.ELSE, Token.THEN)), 498 | }, 499 | ], 500 | }; 501 | } 502 | 503 | exprLoop(): schema.Rule { 504 | return { 505 | name: "meta.exprLoop.wasm", 506 | patterns: [ 507 | { 508 | name: "keyword.control.wasm", 509 | match: words(Token.LOOP), 510 | }, 511 | ], 512 | }; 513 | } 514 | 515 | exprPlain(): schema.Rule { 516 | return { 517 | name: "meta.exprPlain.wasm", 518 | patterns: [ 519 | include(this.instrPlain), 520 | { 521 | begin: Token.LEFT_PARENTHESIS, 522 | beginCaptures: { 523 | 0: { name: "meta.brace.round.wasm" }, 524 | }, 525 | end: Token.RIGHT_PARENTHESIS, 526 | endCaptures: { 527 | 0: { name: "meta.brace.round.wasm" }, 528 | }, 529 | patterns: [include(this.expr)], 530 | }, 531 | ], 532 | }; 533 | } 534 | 535 | extra(): schema.Rule { 536 | return { 537 | name: "meta.extra.wasm", 538 | patterns: [include(this.comment), include(this.annotation)], 539 | }; 540 | } 541 | 542 | funcLocals(): schema.Rule { 543 | return { 544 | name: "meta.funcLocals.wasm", 545 | begin: words(Token.LOCAL), 546 | beginCaptures: { 547 | 0: { name: "keyword.control.local.wasm" }, 548 | }, 549 | end: lookAhead(Token.RIGHT_PARENTHESIS), 550 | patterns: [ 551 | { 552 | name: "variable.parameter.local.wasm", 553 | match: Token.identifier, 554 | }, 555 | include(this.valueType), 556 | ], 557 | }; 558 | } 559 | 560 | funcType(): schema.Rule { 561 | return { 562 | name: "meta.funcType.wasm", 563 | patterns: [include(this.funcTypeParams), include(this.funcTypeResults)], 564 | }; 565 | } 566 | 567 | funcTypeParams(): schema.Rule { 568 | return { 569 | name: "meta.funcTypeParams.wasm", 570 | begin: words(Token.PARAM), 571 | beginCaptures: { 572 | 0: { name: "keyword.control.param.wasm" }, 573 | }, 574 | end: lookAhead(Token.RIGHT_PARENTHESIS), 575 | patterns: [ 576 | include(this.extra), 577 | include(this.valueType), 578 | { 579 | name: "entity.name.type.alias.wasm", 580 | match: Token.id, 581 | }, 582 | ], 583 | }; 584 | } 585 | 586 | funcTypeResults(): schema.Rule { 587 | return { 588 | name: "meta.funcTypeResults.wasm", 589 | begin: words(Token.RESULT), 590 | beginCaptures: { 591 | 0: { name: "keyword.control.param.wasm" }, 592 | }, 593 | end: lookAhead(Token.RIGHT_PARENTHESIS), 594 | patterns: [include(this.extra), include(this.valueType)], 595 | }; 596 | } 597 | 598 | globalType(): schema.Rule { 599 | return { 600 | name: "meta.globalType.wasm", 601 | patterns: [include(this.globalTypeImm), include(this.globalTypeMut)], 602 | }; 603 | } 604 | 605 | globalTypeImm(): schema.Rule { 606 | return { 607 | name: "meta.globalTypeImm.wasm", 608 | patterns: [include(this.valueType)], 609 | }; 610 | } 611 | 612 | globalTypeMut(): schema.Rule { 613 | return { 614 | name: "meta.globalTypeMut.wasm", 615 | patterns: [ 616 | { 617 | begin: Token.LEFT_PARENTHESIS, 618 | beginCaptures: { 619 | 0: { name: "meta.brace.round.wasm" }, 620 | }, 621 | end: Token.RIGHT_PARENTHESIS, 622 | endCaptures: { 623 | 0: { name: "meta.brace.round.wasm" }, 624 | }, 625 | patterns: [ 626 | include(this.extra), 627 | { 628 | begin: lookBehind(Token.LEFT_PARENTHESIS), 629 | end: words(Token.MUT), 630 | endCaptures: { 631 | 0: { name: "storage.modifier.wasm" }, 632 | }, 633 | patterns: [include(this.extra), include(this.valueType)], 634 | }, 635 | ], 636 | }, 637 | ], 638 | }; 639 | } 640 | 641 | importDesc(): schema.Rule { 642 | return { 643 | name: "meta.importDesc.wasm", 644 | begin: Token.LEFT_PARENTHESIS, 645 | beginCaptures: { 646 | 0: { name: "meta.brace.round.wasm" }, 647 | }, 648 | end: Token.RIGHT_PARENTHESIS, 649 | endCaptures: { 650 | 0: { name: "meta.brace.round.wasm" }, 651 | }, 652 | patterns: [ 653 | include(this.importDescFuncType), 654 | include(this.importDescGlobalType), 655 | include(this.importDescMemoryType), 656 | include(this.importDescTableType), 657 | ], 658 | }; 659 | } 660 | 661 | importDescFuncType(): schema.Rule { 662 | // NOTE: merged with importDescTypeUse 663 | return { 664 | name: "meta.importDescFuncType.wasm", 665 | begin: words(Token.FUNC), 666 | beginCaptures: { 667 | 0: { name: "keyword.control.func.wasm" }, 668 | }, 669 | end: lookAhead(Token.RIGHT_PARENTHESIS), 670 | patterns: [ 671 | { 672 | name: "entity.name.function.wasm", 673 | match: Token.identifier, 674 | }, 675 | { 676 | begin: Token.LEFT_PARENTHESIS, 677 | end: Token.RIGHT_PARENTHESIS, 678 | patterns: [include(this.funcType), include(this.typeUse)], 679 | }, 680 | ], 681 | }; 682 | } 683 | 684 | importDescGlobalType(): schema.Rule { 685 | return { 686 | name: "meta.importDescGlobalType.wasm", 687 | begin: words(Token.GLOBAL), 688 | beginCaptures: { 689 | 0: { name: "keyword.control.global.wasm" }, 690 | }, 691 | end: lookAhead(Token.RIGHT_PARENTHESIS), 692 | patterns: [ 693 | { 694 | name: "variable.other.global.wasm", 695 | match: Token.identifier, 696 | }, 697 | include(this.globalType), 698 | ], 699 | }; 700 | } 701 | 702 | importDescMemoryType(): schema.Rule { 703 | return { 704 | name: "meta.importDescMemoryType.wasm", 705 | begin: words(Token.MEMORY), 706 | beginCaptures: { 707 | 0: { name: "keyword.control.memory.wasm" }, 708 | }, 709 | end: lookAhead(Token.RIGHT_PARENTHESIS), 710 | patterns: [ 711 | { 712 | name: "variable.other.memory.wasm", 713 | match: Token.identifier, 714 | }, 715 | include(this.memoryType), 716 | ], 717 | }; 718 | } 719 | 720 | importDescTableType(): schema.Rule { 721 | return { 722 | name: "meta.importDescTableType.wasm", 723 | begin: words(Token.TABLE), 724 | beginCaptures: { 725 | 0: { name: "keyword.control.table.wasm" }, 726 | }, 727 | end: lookAhead(Token.RIGHT_PARENTHESIS), 728 | patterns: [ 729 | { 730 | name: "variable.other.table.wasm", 731 | match: Token.identifier, 732 | }, 733 | include(this.tableType), 734 | ], 735 | }; 736 | } 737 | 738 | inlineExport(): schema.Rule { 739 | return { 740 | name: "meta.inlineExport.wasm", 741 | begin: words(Token.EXPORT), 742 | beginCaptures: { 743 | 0: { name: "keyword.control.export.wasm" }, 744 | }, 745 | end: lookAhead(Token.RIGHT_PARENTHESIS), 746 | patterns: [ 747 | include(this.extra), 748 | { 749 | name: "variable.other.readwrite.alias.wasm", 750 | begin: '"', 751 | end: '(")|((?:[^\\\\\\n])$)', 752 | patterns: [ 753 | { 754 | match: Token.escape, 755 | }, 756 | ], 757 | }, 758 | ], 759 | }; 760 | } 761 | 762 | inlineImport(): schema.Rule { 763 | return { 764 | name: "meta.inlineImport.wasm", 765 | begin: words(Token.IMPORT), 766 | beginCaptures: { 767 | 0: { name: "keyword.control.import.wasm" }, 768 | }, 769 | end: lookAhead(Token.RIGHT_PARENTHESIS), 770 | patterns: [include(this.extra), include(this.inlineImportNames)], 771 | }; 772 | } 773 | 774 | inlineImportNames(): schema.Rule { 775 | return { 776 | name: "meta.inlineImportNames.wasm", 777 | patterns: [ 778 | { 779 | begin: lastWords(Token.IMPORT), 780 | end: lookBehind('"'), 781 | patterns: [ 782 | include(this.extra), 783 | { 784 | name: "entity.name.type.module.wasm", 785 | begin: '"', 786 | end: '(")|((?:[^\\\\\\n])$)', 787 | patterns: [ 788 | { 789 | match: Token.escape, 790 | }, 791 | ], 792 | }, 793 | ], 794 | }, 795 | { 796 | name: "variable.other.readwrite.alias.wasm", 797 | begin: '"', 798 | end: '(")|((?:[^\\\\\\n])$)', 799 | patterns: [ 800 | { 801 | match: Token.escape, 802 | }, 803 | ], 804 | }, 805 | ], 806 | }; 807 | } 808 | 809 | instr(): schema.Rule { 810 | return { 811 | name: "meta.instr.wasm", 812 | patterns: [ 813 | include(this.instrPlain), 814 | include(this.instrCall), 815 | include(this.instrBlock), 816 | { 817 | begin: Token.LEFT_PARENTHESIS, 818 | beginCaptures: { 819 | 0: { name: "meta.brace.round.wasm" }, 820 | }, 821 | end: Token.RIGHT_PARENTHESIS, 822 | endCaptures: { 823 | 0: { name: "meta.brace.round.wasm" }, 824 | }, 825 | patterns: [include(this.expr)], 826 | }, 827 | ], 828 | }; 829 | } 830 | 831 | instrBlock(): schema.Rule { 832 | return { 833 | name: "meta.instrBlock.wasm", 834 | patterns: [include(this.blockBlock), include(this.blockLoop), include(this.blockIf)], 835 | }; 836 | } 837 | 838 | instrCall(): schema.Rule { 839 | return { 840 | name: "meta.instrCall.wasm", 841 | patterns: [], 842 | }; 843 | } 844 | 845 | instrList(): schema.Rule { 846 | return { 847 | name: "meta.instrList.wasm", 848 | patterns: [include(this.instrListCall), include(this.instr)], 849 | }; 850 | } 851 | 852 | instrListCall(): schema.Rule { 853 | return { 854 | name: "meta.instrListCall.wasm", 855 | patterns: [], 856 | }; 857 | } 858 | 859 | instrPlain(): schema.Rule { 860 | return { 861 | name: "meta.instrPlain.wasm", 862 | patterns: [ 863 | include(this.instrPlainUnreachable), 864 | include(this.instrPlainNop), 865 | include(this.instrPlainDrop), 866 | include(this.instrPlainSelect), 867 | include(this.instrPlainBr), 868 | include(this.instrPlainBrIf), 869 | include(this.instrPlainBrTable), 870 | include(this.instrPlainReturn), 871 | include(this.instrPlainLocalGet), 872 | include(this.instrPlainLocalSet), 873 | include(this.instrPlainLocalTee), 874 | include(this.instrPlainGlobalGet), 875 | include(this.instrPlainGlobalSet), 876 | include(this.instrPlainMemorySize), 877 | include(this.instrPlainMemoryGrow), 878 | include(this.instrPlainConst), 879 | include(this.instrPlainTest), 880 | include(this.instrPlainCompare), 881 | include(this.instrPlainUnary), 882 | include(this.instrPlainBinary), 883 | include(this.instrPlainConvert), 884 | include(this.instrPlainLoad), 885 | include(this.instrPlainStore), 886 | include(this.instrPlainCall), 887 | ], 888 | }; 889 | } 890 | 891 | instrPlainBinary(): schema.Rule { 892 | return { 893 | name: "meta.instrPlainBinary.wasm", 894 | patterns: [ 895 | { 896 | name: "keyword.control.wasm", 897 | match: seq(words(Token.instrType), ops(Token.FULL_STOP), group(alt("add", "sub", "mul"))), 898 | }, 899 | { 900 | name: "keyword.control.wasm", 901 | match: seq( 902 | words(Token.instrTypeInt), 903 | ops(Token.FULL_STOP), 904 | group(alt("and", "or", "xor", "shl", "rotl", "rotr")), 905 | ), 906 | }, 907 | { 908 | name: "keyword.control.wasm", 909 | match: seq( 910 | words(Token.instrTypeInt), 911 | ops(Token.FULL_STOP), 912 | words(seq(group(alt("div", "rem", "shr")), "_", set("su"))), 913 | ), 914 | }, 915 | { 916 | name: "keyword.control.wasm", 917 | match: seq( 918 | words(Token.instrTypeFloat), 919 | ops(Token.FULL_STOP), 920 | group(alt("add", "sub", "mul", "div", "min", "max", "copysign")), 921 | ), 922 | }, 923 | ], 924 | }; 925 | } 926 | 927 | instrPlainBr(): schema.Rule { 928 | return { 929 | name: "meta.instrPlainBr.wasm", 930 | begin: words(Token.BR), 931 | beginCaptures: { 932 | 0: { name: "keyword.control.wasm" }, 933 | }, 934 | end: Token.index, 935 | endCaptures: { 936 | 0: { name: "variable.other.constant" }, 937 | }, 938 | }; 939 | } 940 | 941 | instrPlainBrIf(): schema.Rule { 942 | return { 943 | name: "meta.instrPlainBrIf.wasm", 944 | begin: words(Token.BR_IF), 945 | beginCaptures: { 946 | 0: { name: "keyword.control.wasm" }, 947 | }, 948 | end: Token.index, 949 | endCaptures: { 950 | 0: { name: "variable.other.constant" }, 951 | }, 952 | }; 953 | } 954 | 955 | instrPlainBrTable(): schema.Rule { 956 | return { 957 | name: "meta.instrPlainBrTable.wasm", 958 | begin: words(Token.BR_TABLE), 959 | beginCaptures: { 960 | 0: { name: "keyword.control.wasm" }, 961 | }, 962 | end: Token.instrEnd, 963 | patterns: [ 964 | { 965 | name: "variable.other.constant", 966 | match: Token.index, 967 | }, 968 | ], 969 | }; 970 | } 971 | 972 | instrPlainCall(): schema.Rule { 973 | return { 974 | name: "meta.instrPlainCall.wasm", 975 | begin: words(Token.CALL), 976 | beginCaptures: { 977 | 0: { name: "keyword.control.wasm" }, 978 | }, 979 | end: Token.index, 980 | endCaptures: { 981 | 0: { name: "variable.other.constant" }, 982 | }, 983 | }; 984 | } 985 | 986 | instrPlainCompare(): schema.Rule { 987 | return { 988 | name: "meta.instrPlainCompare.wasm", 989 | patterns: [ 990 | { 991 | name: "keyword.control.wasm", 992 | match: seq(words(Token.instrType), ops(Token.FULL_STOP), words(group(alt("eq", "ne")))), 993 | }, 994 | { 995 | name: "keyword.control.wasm", 996 | match: seq( 997 | words(Token.instrTypeInt), 998 | ops(Token.FULL_STOP), 999 | words(seq(group(alt("lt", "le", "gt", "ge")), "_", set("su"))), 1000 | ), 1001 | }, 1002 | { 1003 | name: "keyword.control.wasm", 1004 | match: seq(words(Token.instrTypeFloat), ops(Token.FULL_STOP), words(group(alt("lt", "le", "gt", "ge")))), 1005 | }, 1006 | ], 1007 | }; 1008 | } 1009 | 1010 | instrPlainConst(): schema.Rule { 1011 | return { 1012 | name: "meta.instrPlainConst.wasm", 1013 | begin: seq(words(Token.instrType), ops(Token.FULL_STOP), words(Token.CONST)), 1014 | beginCaptures: { 1015 | 0: { name: "keyword.control.wasm" }, 1016 | }, 1017 | end: alt( 1018 | capture(seq(opt(Token.sign), words(group(alt(Token.hexfloat, seq("nan:", Token.hexfloat)))))), 1019 | capture(seq(opt(Token.sign), Token.float)), 1020 | capture(seq(opt(Token.sign), words(group(alt("inf", "nan"))))), 1021 | capture(seq(opt(Token.sign), seq("0x", Token.hexnum))), 1022 | capture(seq(opt(Token.sign), Token.num)), 1023 | ), 1024 | endCaptures: { 1025 | 1: { name: "constant.numeric.float.hexadecimal.wasm" }, 1026 | 2: { name: "constant.numeric.float.decimal.wasm" }, 1027 | 3: { name: "constant.numeric.float.wasm" }, 1028 | 4: { name: "constant.numeric.integer.hexadecimal.wasm" }, 1029 | 5: { name: "constant.numeric.integer.decimal.wasm" }, 1030 | }, 1031 | }; 1032 | } 1033 | 1034 | instrPlainConvert(): schema.Rule { 1035 | return { 1036 | name: "meta.instrPlainConvert.wasm", 1037 | patterns: [ 1038 | { 1039 | name: "keyword.control.wasm", 1040 | match: seq(words(Token.instrTypeInt32), ops(Token.FULL_STOP), words("wrap_i64")), 1041 | }, 1042 | { 1043 | name: "keyword.control.wasm", 1044 | match: seq(words(Token.instrTypeInt64), ops(Token.FULL_STOP), words(seq("extend_i32_", set("su")))), 1045 | }, 1046 | { 1047 | name: "keyword.control.wasm", 1048 | match: seq(words(Token.instrTypeFloat32), ops(Token.FULL_STOP), words("demote_f64")), 1049 | }, 1050 | { 1051 | name: "keyword.control.wasm", 1052 | match: seq(words(Token.instrTypeFloat64), ops(Token.FULL_STOP), words("promote_f32")), 1053 | }, 1054 | { 1055 | name: "keyword.control.wasm", 1056 | match: seq( 1057 | words(Token.instrTypeInt), 1058 | ops(Token.FULL_STOP), 1059 | words(seq("trunc", opt("_sat"), "_f", group(alt("32", "64")), "_", set("su"))), 1060 | ), 1061 | }, 1062 | { 1063 | name: "keyword.control.wasm", 1064 | match: seq( 1065 | words(Token.instrTypeFloat), 1066 | ops(Token.FULL_STOP), 1067 | words(seq("convert_i", group(alt("32", "64")), "_", set("su"))), 1068 | ), 1069 | }, 1070 | { 1071 | name: "keyword.control.wasm", 1072 | match: seq(words(Token.instrTypeInt32), ops(Token.FULL_STOP), words("reinterpret_f32")), 1073 | }, 1074 | { 1075 | name: "keyword.control.wasm", 1076 | match: seq(words(Token.instrTypeInt64), ops(Token.FULL_STOP), words("reinterpret_f64")), 1077 | }, 1078 | { 1079 | name: "keyword.control.wasm", 1080 | match: seq(words(Token.instrTypeFloat32), ops(Token.FULL_STOP), words("reinterpret_i32")), 1081 | }, 1082 | { 1083 | name: "keyword.control.wasm", 1084 | match: seq(words(Token.instrTypeFloat64), ops(Token.FULL_STOP), words("reinterpret_i64")), 1085 | }, 1086 | ], 1087 | }; 1088 | } 1089 | 1090 | instrPlainDrop(): schema.Rule { 1091 | return { 1092 | name: "meta.instrPlainDrop.wasm keyword.control.wasm", 1093 | match: words(Token.DROP), 1094 | }; 1095 | } 1096 | 1097 | instrPlainGlobalGet(): schema.Rule { 1098 | return { 1099 | name: "meta.instrPlainGlobalGet.wasm", 1100 | begin: words(Token.GLOBAL_GET), 1101 | beginCaptures: { 1102 | 0: { name: "keyword.control.wasm" }, 1103 | }, 1104 | end: Token.index, 1105 | endCaptures: { 1106 | 0: { name: "variable.other.constant" }, 1107 | }, 1108 | }; 1109 | } 1110 | 1111 | instrPlainGlobalSet(): schema.Rule { 1112 | return { 1113 | name: "meta.instrPlainGlobalSet.wasm", 1114 | begin: words(Token.GLOBAL_SET), 1115 | beginCaptures: { 1116 | 0: { name: "keyword.control.wasm" }, 1117 | }, 1118 | end: Token.index, 1119 | endCaptures: { 1120 | 0: { name: "variable.other.constant" }, 1121 | }, 1122 | }; 1123 | } 1124 | 1125 | instrPlainLoad(): schema.Rule { 1126 | const patterns = [include(this.offsetValue), include(this.alignValue)]; 1127 | const end = alt(negativeLookAhead("\\G"), negativeLookAhead(set(Class.space))); 1128 | return { 1129 | name: "meta.instrPlainLoad.wasm", 1130 | patterns: [ 1131 | { 1132 | begin: seq(words(Token.instrTypeInt64), ops(Token.FULL_STOP), words(seq("load", "32", "_", set("su")))), 1133 | beginCaptures: { 1134 | 0: { name: "keyword.control.wasm" }, 1135 | }, 1136 | end, 1137 | patterns, 1138 | }, 1139 | { 1140 | begin: seq( 1141 | words(Token.instrTypeInt), 1142 | ops(Token.FULL_STOP), 1143 | words(seq("load", group(alt("8", "16")), "_", set("su"))), 1144 | ), 1145 | beginCaptures: { 1146 | 0: { name: "keyword.control.wasm" }, 1147 | }, 1148 | end, 1149 | patterns, 1150 | }, 1151 | { 1152 | begin: seq(words(Token.instrType), ops(Token.FULL_STOP), words("load")), 1153 | beginCaptures: { 1154 | 0: { name: "keyword.control.wasm" }, 1155 | }, 1156 | end, 1157 | patterns, 1158 | }, 1159 | ], 1160 | }; 1161 | } 1162 | 1163 | instrPlainLocalGet(): schema.Rule { 1164 | return { 1165 | name: "meta.instrPlainLocalGet.wasm", 1166 | begin: words(Token.LOCAL_GET), 1167 | beginCaptures: { 1168 | 0: { name: "keyword.control.wasm" }, 1169 | }, 1170 | end: Token.index, 1171 | endCaptures: { 1172 | 0: { name: "variable.other.constant" }, 1173 | }, 1174 | }; 1175 | } 1176 | 1177 | instrPlainLocalSet(): schema.Rule { 1178 | return { 1179 | name: "meta.instrPlainLocalSet.wasm", 1180 | begin: words(Token.LOCAL_SET), 1181 | beginCaptures: { 1182 | 0: { name: "keyword.control.wasm" }, 1183 | }, 1184 | end: Token.index, 1185 | endCaptures: { 1186 | 0: { name: "variable.other.constant" }, 1187 | }, 1188 | }; 1189 | } 1190 | 1191 | instrPlainLocalTee(): schema.Rule { 1192 | return { 1193 | name: "meta.instrPlainLocalTee.wasm", 1194 | begin: words(Token.LOCAL_TEE), 1195 | beginCaptures: { 1196 | 0: { name: "keyword.control.wasm" }, 1197 | }, 1198 | end: Token.index, 1199 | endCaptures: { 1200 | 0: { name: "variable.other.constant" }, 1201 | }, 1202 | }; 1203 | } 1204 | 1205 | instrPlainMemoryGrow(): schema.Rule { 1206 | return { 1207 | name: "meta.instrPlainMemoryGrow.wasm keyword.control.wasm", 1208 | match: words(Token.MEMORY_GROW), 1209 | }; 1210 | } 1211 | 1212 | instrPlainMemorySize(): schema.Rule { 1213 | return { 1214 | name: "meta.instrPlainMemorySize.wasm keyword.control.wasm", 1215 | match: words(Token.MEMORY_SIZE), 1216 | }; 1217 | } 1218 | 1219 | instrPlainNop(): schema.Rule { 1220 | return { 1221 | name: "meta.instrPlainNop.wasm keyword.control.wasm", 1222 | match: words(Token.NOP), 1223 | }; 1224 | } 1225 | 1226 | instrPlainReturn(): schema.Rule { 1227 | return { 1228 | name: "meta.instrPlainReturn.wasm keyword.control.wasm", 1229 | match: words(Token.RETURN), 1230 | }; 1231 | } 1232 | 1233 | instrPlainSelect(): schema.Rule { 1234 | return { 1235 | name: "meta.instrPlainSelect.wasm keyword.control.wasm", 1236 | match: words(Token.SELECT), 1237 | }; 1238 | } 1239 | 1240 | instrPlainStore(): schema.Rule { 1241 | const patterns = [include(this.offsetValue), include(this.alignValue)]; 1242 | const end = alt(negativeLookAhead("\\G"), negativeLookAhead(set(Class.space))); 1243 | return { 1244 | name: "meta.instrPlainStore.wasm", 1245 | patterns: [ 1246 | { 1247 | begin: seq(words(Token.instrTypeInt64), ops(Token.FULL_STOP), words(seq("store", "32"))), 1248 | beginCaptures: { 1249 | 0: { name: "keyword.control.wasm" }, 1250 | }, 1251 | end, 1252 | patterns, 1253 | }, 1254 | { 1255 | begin: seq(words(Token.instrTypeInt), ops(Token.FULL_STOP), words(seq("store", group(alt("8", "16"))))), 1256 | beginCaptures: { 1257 | 0: { name: "keyword.control.wasm" }, 1258 | }, 1259 | end, 1260 | patterns, 1261 | }, 1262 | { 1263 | begin: seq(words(Token.instrType), ops(Token.FULL_STOP), words("store")), 1264 | beginCaptures: { 1265 | 0: { name: "keyword.control.wasm" }, 1266 | }, 1267 | end, 1268 | patterns, 1269 | }, 1270 | ], 1271 | }; 1272 | } 1273 | 1274 | instrPlainTest(): schema.Rule { 1275 | return { 1276 | name: "meta.instrPlainTest.wasm keyword.control.wasm", 1277 | match: seq(words(Token.instrType), ops(Token.FULL_STOP), words("eqz")), 1278 | }; 1279 | } 1280 | 1281 | instrPlainUnary(): schema.Rule { 1282 | return { 1283 | name: "meta.instrPlainUnary.wasm", 1284 | patterns: [ 1285 | { 1286 | name: "keyword.control.wasm", 1287 | match: seq(words(Token.instrTypeInt), ops(Token.FULL_STOP), words(group(alt("clz", "ctz", "popcnt")))), 1288 | }, 1289 | { 1290 | name: "keyword.control.wasm", 1291 | match: seq( 1292 | words(Token.instrTypeInt), 1293 | ops(Token.FULL_STOP), 1294 | words(group(seq("extend", group(alt("8", "16")), "_s"))), 1295 | ), 1296 | }, 1297 | { 1298 | name: "keyword.control.wasm", 1299 | match: seq(words(Token.instrTypeInt64), ops(Token.FULL_STOP), words("extend32_s")), 1300 | }, 1301 | { 1302 | name: "keyword.control.wasm", 1303 | match: seq( 1304 | words(Token.instrTypeFloat), 1305 | ops(Token.FULL_STOP), 1306 | words(group(alt("neg", "abs", "sqrt", "ceil", "floor", "trunc", "nearest"))), 1307 | ), 1308 | }, 1309 | ], 1310 | }; 1311 | } 1312 | 1313 | instrPlainUnreachable(): schema.Rule { 1314 | return { 1315 | name: "meta.instrPlainUnreachable.wasm keyword.control.wasm", 1316 | match: words(Token.UNREACHABLE), 1317 | }; 1318 | } 1319 | 1320 | limits(): schema.Rule { 1321 | return { 1322 | name: "meta.limits.wasm constant.numeric.integer", 1323 | match: Token.uN, 1324 | }; 1325 | } 1326 | 1327 | lineComment(): schema.Rule { 1328 | return { 1329 | name: "meta.comment.line.wasm", 1330 | begin: seq(opt(capture(seq("^", manyOne(set(" ", "\\t"))))), capture(capture(";;"))), 1331 | beginCaptures: { 1332 | 1: { name: "punctuation.whitespace.comment.leading.wasm" }, 1333 | 2: { name: "comment.line.double-semicolon.wasm" }, 1334 | 3: { name: "punctuation.definition.comment.wasm" }, 1335 | }, 1336 | end: lookAhead("$"), 1337 | contentName: "comment.line.double-semicolon.wasm", 1338 | }; 1339 | } 1340 | 1341 | memoryFieldsData(): schema.Rule { 1342 | return { 1343 | name: "meta.memoryFieldsData.wasm", 1344 | begin: words(Token.DATA), 1345 | beginCaptures: { 1346 | 0: { name: "storage.type.memory.wasm" }, 1347 | }, 1348 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1349 | patterns: [include(this.string)], 1350 | }; 1351 | } 1352 | 1353 | memoryFieldsType(): schema.Rule { 1354 | return { 1355 | name: "meta.memoryFieldsType.wasm", 1356 | patterns: [include(this.inlineImport), include(this.memoryType)], 1357 | }; 1358 | } 1359 | 1360 | memoryType(): schema.Rule { 1361 | return { 1362 | name: "meta.memoryType.wasm", 1363 | patterns: [include(this.limits)], 1364 | }; 1365 | } 1366 | 1367 | module(): schema.Rule { 1368 | return { 1369 | name: "meta.module.wasm", 1370 | begin: words(Token.MODULE), 1371 | beginCaptures: { 1372 | 0: { name: "storage.type.module.wasm" }, 1373 | }, 1374 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1375 | patterns: [ 1376 | include(this.extra), 1377 | { 1378 | begin: Token.id, 1379 | beginCaptures: { 1380 | 0: { name: "entity.name.type.module.wasm" }, 1381 | }, 1382 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1383 | patterns: [include(this.extra), include(this.moduleField)], 1384 | }, 1385 | include(this.moduleField), 1386 | ], 1387 | }; 1388 | } 1389 | 1390 | moduleField(): schema.Rule { 1391 | return { 1392 | name: "meta.moduleField.wasm", 1393 | patterns: [ 1394 | include(this.extra), 1395 | include(this.moduleFieldData), 1396 | include(this.moduleFieldElem), 1397 | include(this.moduleFieldExport), 1398 | include(this.moduleFieldFunc), 1399 | include(this.moduleFieldGlobal), 1400 | include(this.moduleFieldImport), 1401 | include(this.moduleFieldMemory), 1402 | include(this.moduleFieldStart), 1403 | include(this.moduleFieldTable), 1404 | include(this.moduleFieldType), 1405 | ], 1406 | }; 1407 | } 1408 | 1409 | moduleFieldData(): schema.Rule { 1410 | return { 1411 | name: "meta.moduleFieldData.wasm", 1412 | begin: words(Token.DATA), 1413 | beginCaptures: { 1414 | 0: { name: "storage.type.data.wasm" }, 1415 | }, 1416 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1417 | patterns: [ 1418 | include(this.extra), 1419 | { 1420 | name: "variable.other.constant entity.name.data.wasm", 1421 | match: Token.index, 1422 | }, 1423 | include(this.offset), 1424 | include(this.string), 1425 | ], 1426 | }; 1427 | } 1428 | 1429 | moduleFieldElem(): schema.Rule { 1430 | return { 1431 | name: "meta.moduleFieldElem.wasm", 1432 | begin: words(Token.ELEM), 1433 | beginCaptures: { 1434 | 0: { name: "storage.type.elem.wasm" }, 1435 | }, 1436 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1437 | patterns: [ 1438 | include(this.extra), 1439 | include(this.offset), 1440 | { 1441 | name: "variable.other.wasm", 1442 | match: Token.index, 1443 | }, 1444 | ], 1445 | }; 1446 | } 1447 | 1448 | moduleFieldExport(): schema.Rule { 1449 | return { 1450 | name: "meta.moduleFieldExport.wasm", 1451 | begin: words(Token.EXPORT), 1452 | beginCaptures: { 1453 | 0: { name: "keyword.control.export.wasm" }, 1454 | }, 1455 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1456 | patterns: [ 1457 | include(this.extra), 1458 | { 1459 | name: "variable.other.readwrite.alias.wasm", 1460 | begin: '"', 1461 | end: '(")|((?:[^\\\\\\n])$)', 1462 | patterns: [ 1463 | { 1464 | match: Token.escape, 1465 | }, 1466 | ], 1467 | }, 1468 | { 1469 | begin: Token.LEFT_PARENTHESIS, 1470 | beginCaptures: { 1471 | 0: { name: "meta.brace.round.wasm" }, 1472 | }, 1473 | end: Token.RIGHT_PARENTHESIS, 1474 | endCaptures: { 1475 | 0: { name: "meta.brace.round.wasm" }, 1476 | }, 1477 | patterns: [include(this.exportDesc)], 1478 | }, 1479 | ], 1480 | }; 1481 | } 1482 | 1483 | moduleFieldFunc(): schema.Rule { 1484 | return { 1485 | name: "meta.moduleFieldFunc.wasm", 1486 | begin: words(Token.FUNC), 1487 | beginCaptures: { 1488 | 0: { name: "storage.type.function.wasm" }, 1489 | }, 1490 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1491 | patterns: [ 1492 | include(this.extra), 1493 | { 1494 | name: "entity.name.function.wasm", 1495 | match: Token.identifier, 1496 | }, 1497 | { 1498 | begin: Token.LEFT_PARENTHESIS, 1499 | beginCaptures: { 1500 | 0: { name: "meta.brace.round.wasm" }, 1501 | }, 1502 | end: Token.RIGHT_PARENTHESIS, 1503 | endCaptures: { 1504 | 0: { name: "meta.brace.round.wasm" }, 1505 | }, 1506 | patterns: [ 1507 | include(this.inlineExport), 1508 | include(this.inlineImport), 1509 | include(this.typeUse), 1510 | include(this.funcTypeParams), 1511 | include(this.funcTypeResults), 1512 | include(this.funcLocals), 1513 | include(this.expr), 1514 | ], 1515 | }, 1516 | include(this.instrList), 1517 | ], 1518 | }; 1519 | } 1520 | 1521 | moduleFieldGlobal(): schema.Rule { 1522 | return { 1523 | name: "meta.moduleFieldGlobal.wasm", 1524 | begin: words(Token.GLOBAL), 1525 | beginCaptures: { 1526 | 0: { name: "storage.type.global.wasm" }, 1527 | }, 1528 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1529 | patterns: [ 1530 | include(this.extra), 1531 | { 1532 | name: "variable.other.global.wasm", 1533 | match: Token.identifier, 1534 | }, 1535 | { 1536 | begin: Token.LEFT_PARENTHESIS, 1537 | beginCaptures: { 1538 | 0: { name: "meta.brace.round.wasm" }, 1539 | }, 1540 | end: Token.RIGHT_PARENTHESIS, 1541 | endCaptures: { 1542 | 0: { name: "meta.brace.round.wasm" }, 1543 | }, 1544 | patterns: [include(this.extra), include(this.inlineExport), include(this.inlineImport)], 1545 | }, 1546 | include(this.globalType), 1547 | include(this.expr), 1548 | ], 1549 | }; 1550 | } 1551 | 1552 | moduleFieldImport(): schema.Rule { 1553 | return { 1554 | name: "meta.moduleFieldImport.wasm", 1555 | begin: words(Token.IMPORT), 1556 | beginCaptures: { 1557 | 0: { name: "keyword.control.import.wasm" }, 1558 | }, 1559 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1560 | patterns: [include(this.extra), include(this.inlineImportNames), include(this.importDesc)], 1561 | }; 1562 | } 1563 | 1564 | moduleFieldMemory(): schema.Rule { 1565 | return { 1566 | name: "meta.moduleFieldMemory.wasm", 1567 | begin: words(Token.MEMORY), 1568 | beginCaptures: { 1569 | 0: { name: "storage.type.memory.wasm" }, 1570 | }, 1571 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1572 | patterns: [ 1573 | include(this.extra), 1574 | { 1575 | name: "variable.other.memory.wasm", 1576 | match: Token.identifier, 1577 | }, 1578 | include(this.memoryFieldsType), 1579 | { 1580 | begin: Token.LEFT_PARENTHESIS, 1581 | beginCaptures: { 1582 | 0: { name: "meta.brace.round.wasm" }, 1583 | }, 1584 | end: Token.RIGHT_PARENTHESIS, 1585 | endCaptures: { 1586 | 0: { name: "meta.brace.round.wasm" }, 1587 | }, 1588 | patterns: [include(this.inlineExport), include(this.memoryFieldsData)], 1589 | }, 1590 | ], 1591 | }; 1592 | } 1593 | 1594 | moduleFieldStart(): schema.Rule { 1595 | return { 1596 | name: "meta.moduleFieldStart.wasm", 1597 | begin: words(Token.START), 1598 | beginCaptures: { 1599 | 0: { name: "keyword.control.start.wasm" }, 1600 | }, 1601 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1602 | patterns: [ 1603 | include(this.extra), 1604 | { 1605 | begin: Token.id, 1606 | beginCaptures: { 1607 | 0: { name: "entity.name.function.wasm" }, 1608 | }, 1609 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1610 | }, 1611 | ], 1612 | }; 1613 | } 1614 | 1615 | moduleFieldTable(): schema.Rule { 1616 | return { 1617 | name: "meta.moduleFieldTable.wasm", 1618 | begin: words(Token.TABLE), 1619 | beginCaptures: { 1620 | 0: { name: "storage.type.table.wasm" }, 1621 | }, 1622 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1623 | patterns: [ 1624 | include(this.extra), 1625 | { 1626 | name: "variable.other.table.wasm", 1627 | match: Token.identifier, 1628 | }, 1629 | { 1630 | // NOTE: these are refactored out of `tableFieldsElem` and 1631 | // `tableFieldsType` since we can't effectively lookahead (beyond 1632 | // parens) in the TextMate grammar. 1633 | patterns: [include(this.limits), include(this.elemType)], 1634 | }, 1635 | { 1636 | begin: Token.LEFT_PARENTHESIS, 1637 | beginCaptures: { 1638 | 0: { name: "meta.brace.round.wasm" }, 1639 | }, 1640 | end: Token.RIGHT_PARENTHESIS, 1641 | endCaptures: { 1642 | 0: { name: "meta.brace.round.wasm" }, 1643 | }, 1644 | patterns: [ 1645 | include(this.extra), 1646 | include(this.inlineExport), 1647 | include(this.tableFieldsElem), 1648 | include(this.tableFieldsType), 1649 | ], 1650 | }, 1651 | ], 1652 | }; 1653 | } 1654 | 1655 | moduleFieldType(): schema.Rule { 1656 | return { 1657 | name: "meta.moduleFieldType.wasm", 1658 | begin: words(Token.TYPE), 1659 | beginCaptures: { 1660 | 0: { name: "storage.type.type.wasm" }, 1661 | }, 1662 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1663 | patterns: [ 1664 | include(this.extra), 1665 | { 1666 | name: "entity.name.type.alias.wasm", 1667 | match: Token.identifier, 1668 | }, 1669 | include(this.typeField), 1670 | ], 1671 | }; 1672 | } 1673 | 1674 | offset(): schema.Rule { 1675 | return { 1676 | name: "meta.offset.wasm", 1677 | begin: Token.LEFT_PARENTHESIS, 1678 | beginCaptures: { 1679 | 0: { name: "meta.brace.round.wasm" }, 1680 | }, 1681 | end: Token.RIGHT_PARENTHESIS, 1682 | endCaptures: { 1683 | 0: { name: "meta.brace.round.wasm" }, 1684 | }, 1685 | patterns: [include(this.offsetConstExpr), include(this.offsetExpr)], 1686 | }; 1687 | } 1688 | 1689 | offsetConstExpr(): schema.Rule { 1690 | return { 1691 | name: "meta.offsetConstExpr.wasm", 1692 | begin: words(Token.OFFSET), 1693 | beginCaptures: { 1694 | 0: { name: "storage.type.type.wasm" }, 1695 | }, 1696 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1697 | patterns: [include(this.instr)], 1698 | }; 1699 | } 1700 | 1701 | offsetExpr(): schema.Rule { 1702 | return { 1703 | name: "meta.offsetExpr.wasm", 1704 | patterns: [include(this.expr)], 1705 | }; 1706 | } 1707 | 1708 | offsetValue(): schema.Rule { 1709 | return { 1710 | begin: seq(manyOne(set(Class.space)), capture(words(seq("offset=", group(alt(Token.num, `0x${Token.hexnum}`)))))), 1711 | end: alt(negativeLookAhead("\\G"), negativeLookAhead(set(Class.space))), 1712 | beginCaptures: { 1713 | 1: { name: "storage.modifier.wasm" }, 1714 | }, 1715 | patterns: [include(this.alignValue)], 1716 | }; 1717 | } 1718 | 1719 | name(): schema.Rule { 1720 | return { 1721 | name: "meta.name.wasm", 1722 | patterns: [include(this.string)], 1723 | }; 1724 | } 1725 | 1726 | string(): schema.Rule { 1727 | return { 1728 | name: "meta.string.wasm string.quoted.double.wasm", 1729 | begin: '"', 1730 | beginCaptures: { 1731 | 0: { name: "punctuation.definition.string.begin.wasm" }, 1732 | }, 1733 | end: '(")|((?:[^\\\\\\n])$)', 1734 | endCaptures: { 1735 | 1: { name: "punctuation.definition.string.end.wasm" }, 1736 | 2: { name: "invalid.illegal.newline.wasm" }, 1737 | }, 1738 | patterns: [include(this.stringCharacterEscape)], 1739 | }; 1740 | } 1741 | 1742 | stringCharacterEscape(): schema.Rule { 1743 | return { 1744 | name: "meta.stringCharacterEscape.wasm constant.character.escape.wasm", 1745 | match: Token.escape, 1746 | }; 1747 | } 1748 | 1749 | tableFieldsElem(): schema.Rule { 1750 | return { 1751 | name: "meta.tableFieldsElem.wasm", 1752 | begin: words(Token.ELEM), 1753 | beginCaptures: { 1754 | 0: { name: "storage.type.elem.wasm" }, 1755 | }, 1756 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1757 | patterns: [ 1758 | include(this.extra), 1759 | { 1760 | name: "variable.other.constant", 1761 | match: Token.index, 1762 | }, 1763 | ], 1764 | }; 1765 | } 1766 | 1767 | tableFieldsType(): schema.Rule { 1768 | return { 1769 | name: "meta.tableFieldsType.wasm", 1770 | patterns: [include(this.inlineImport), include(this.tableType)], 1771 | }; 1772 | } 1773 | 1774 | tableType(): schema.Rule { 1775 | return { 1776 | name: "meta.tableType.wasm", 1777 | patterns: [include(this.limits), include(this.elemType)], 1778 | }; 1779 | } 1780 | 1781 | typeField(): schema.Rule { 1782 | return { 1783 | name: "meta.typeField.wasm", 1784 | begin: Token.LEFT_PARENTHESIS, 1785 | beginCaptures: { 1786 | 0: { name: "meta.brace.round.wasm" }, 1787 | }, 1788 | end: Token.RIGHT_PARENTHESIS, 1789 | endCaptures: { 1790 | 0: { name: "meta.brace.round.wasm" }, 1791 | }, 1792 | patterns: [ 1793 | include(this.extra), 1794 | { 1795 | begin: lookBehind(Token.LEFT_PARENTHESIS), 1796 | end: words(Token.FUNC), 1797 | endCaptures: { 1798 | 0: { name: "storage.type.function.wasm" }, 1799 | }, 1800 | }, 1801 | { 1802 | begin: Token.LEFT_PARENTHESIS, 1803 | beginCaptures: { 1804 | 0: { name: "meta.brace.round.wasm" }, 1805 | }, 1806 | end: Token.RIGHT_PARENTHESIS, 1807 | endCaptures: { 1808 | 0: { name: "meta.brace.round.wasm" }, 1809 | }, 1810 | patterns: [include(this.extra), include(this.funcType)], 1811 | }, 1812 | ], 1813 | }; 1814 | } 1815 | 1816 | typeUse(): schema.Rule { 1817 | return { 1818 | name: "meta.typeUse.wasm", 1819 | begin: words(Token.TYPE), 1820 | beginCaptures: { 1821 | 0: { name: "storage.type.type.wasm" }, 1822 | }, 1823 | end: lookAhead(Token.RIGHT_PARENTHESIS), 1824 | patterns: [ 1825 | { 1826 | name: "entity.name.type.alias.wasm", 1827 | match: Token.index, 1828 | }, 1829 | ], 1830 | }; 1831 | } 1832 | 1833 | valueType(): schema.Rule { 1834 | return { 1835 | name: "meta.valueType.wasm storage.valueType.wasm", 1836 | match: Token.valueType, 1837 | }; 1838 | } 1839 | } 1840 | 1841 | export default new Wat().render(); 1842 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as client from "./client"; 2 | import * as lspClient from "vscode-languageclient/node"; 3 | 4 | let languageClient: lspClient.LanguageClient; 5 | 6 | export function activate(): Promise { 7 | return client.launch().then((result) => { 8 | languageClient = result; 9 | }); 10 | } 11 | 12 | export function deactivate(): Promise | undefined { 13 | if (null == languageClient) { 14 | return undefined; 15 | } 16 | return languageClient.stop(); 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": false, 4 | "allowSyntheticDefaultImports": true, 5 | "allowUnreachableCode": false, 6 | "allowUnusedLabels": false, 7 | "checkJs": false, 8 | "declaration": true, 9 | "esModuleInterop": true, 10 | "experimentalDecorators": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "lib": ["dom", "es2020"], 13 | "module": "commonjs", 14 | "moduleResolution": "node", 15 | "newLine": "LF", 16 | "noEmitOnError": true, 17 | "noErrorTruncation": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "noImplicitAny": true, 20 | "noImplicitReturns": true, 21 | "noImplicitThis": true, 22 | "noUnusedLocals": true, 23 | "noUnusedParameters": true, 24 | "outDir": "out", 25 | "pretty": true, 26 | "removeComments": true, 27 | "resolveJsonModule": true, 28 | "rootDir": "src", 29 | "skipLibCheck": true, 30 | "sourceMap": true, 31 | "strict": true, 32 | "strictPropertyInitialization": false, 33 | "suppressImplicitAnyIndexErrors": false, 34 | "target": "es2020" 35 | }, 36 | "include": ["src"] 37 | } 38 | --------------------------------------------------------------------------------