Welle is a small, dynamically typed programming language with curly-brace blocks, newline/semicolon statement separators, a tree-walk interpreter, and an optional bytecode VM. It also ships with a formatter, linter, and a VS Code extension (syntax highlighting + LSP features).
Status: early but usable. The language is evolving; see the spec and “VM limitations” below.
- Full language spec: docs/spec.md
- Formatting verification notes: docs/formatting.md
- VS Code extension source: vscode-welle/
- Curly-brace blocks:
{ ... } - Newlines are statement separators (like
;); semicolons are supported - Variables, assignments, and expressions
- Control flow:
if/else,while,for (...),break,continue switchstatement andmatchexpression- Named functions (
func name(...) { ... }) + closures (captures for reads) - Arrays (
[...]), dicts (#{...}), indexing, slicing (strings slice by Unicode code points) - Exceptions:
throw,try/catch/finally, anddefer(LIFO)
- CLI runner + REPL
- Formatter:
welle fmt - Linter:
welle lint - Language Server (LSP): diagnostics, semantic tokens, go-to-definition, document symbols, quick fixes, formatting
You need Go installed.
# From the repo root
go test ./...
go build -o bin/welle ./cmd/welle
go build -o bin/welle-lsp ./cmd/welle-lsp
# Run
./bin/welle run examples/is_palindrome.wll
./bin/welle replIf I ever finish the repo releases with prebuilt binaries, download the latest one and put it on your PATH.
Create a file hello.wll:
print("Hello from Welle!")
Run:
welle run hello.wll
# or (if you built locally)
./bin/welle run hello.wllRun a file (or a “spec” string if you pass code directly):
welle [run] <pathOrSpec>Start REPL:
welle repl
# or just:
welleUseful flags:
-tokensprint lexer tokens-astprint AST-vmrun using the bytecode VM-disdump VM bytecode (implies-vm)-Oenable bytecode optimizer (VM only)
Subcommands:
welle replwelle gfx [pathOrSpec]welle init [--name <name>] [--entry <file>] [--force]welle fmt [-w] [-i <indent>] <path|dir>welle lint <file|dir>...welle tools install [--bin <dir>]
Format a file to stdout:
welle fmt examples/is_palindrome.wllWrite changes in place:
welle fmt -w examples/is_palindrome.wllFormat a directory:
welle fmt -w examplesNotes:
- Token-based formatter (not AST-based)
- Normalizes spacing around operators/punctuation
- Puts
{and}on their own lines and indents blocks - Converts
;into line breaks - Collapses multiple blank lines to at most one
- Ensures a trailing newline
welle lint examplesWarnings:
WL0001unused variableWL0002unused parameterWL0003unreachable code (afterreturnorthrowin a block)WL0004variable shadows outer variable (enabled by default)
Parser errors use code WP0001.
Welle has two execution engines:
- Interpreter (tree-walk) — the most complete feature set today.
- VM (bytecode) — faster and powers the REPL/LSP, but has some gaps.
Known VM limitations (current):
-
The bytecode compiler does not support:
- logical operators
and/or - string operators (e.g. string concatenation with
+)
- logical operators
-
for-inis interpreter-only (for x in expr { ... }) -
Assigning to a captured free variable is unsupported (compile error)
If you hit a limitation, try running without -vm:
welle run myfile.wll
# instead of:
welle -vm run myfile.wllWelle includes a small graphics API exposed via builtins and stdlib (std:gfx, std:image, std:noise, etc.).
Run GFX scripts using:
welle gfx examples/gfx_demo.wllA typical pattern is:
setup()called once (open window, allocate buffers)draw()called every frame (begin_frame → draw → end_frame)
Check examples/gfx_*.wll for working demos.
The std/ folder contains Welle modules you can import, e.g.:
import "std:math" as math
import "std:rand" as rand
import "std:color" as color
import "std:noise" as noise
import "std:gfx" as gfx
import "std:image" as image
See docs/spec.md for the full list of builtins and stdlib functions.
The extension lives in vscode-welle/ and provides:
- Syntax highlighting for
.wll - Language configuration (brackets, comments, etc.)
- LSP features (diagnostics, semantic tokens, go-to-definition, symbols, quick fixes, formatting)
From the VS Code marketplace:
- Open VS Code.
- Go to Extensions view (Ctrl+Shift+X).
- Search for “Welle” and install the extension by “welle".
Or just install it from the marketplace link: https://marketplace.visualstudio.com/items?itemName=welle.welle
From vscode-welle/:
npm install
npx vsce packageThe extension’s prepublish script builds the bundled LSP server automatically:
npm run build:lsp→ buildscmd/welle-lspintovscode-welle/server/welle-lspvscode:prepublishalso runschmod +x server/welle-lsp
Then install the produced .vsix in VS Code:
- Extensions view →
...→ Install from VSIX...
Open a .wll file and run:
- Format Document (Shift+Alt+F)
If formatting does not trigger:
- Ensure the file extension is
.wll - Check the Output panel for “Welle” logs
- Make sure your extension is activated and the LSP started
See docs/formatting.md for the smoke test.
This repo includes the Welle icon at:
assets/welle.svg
If you use the “VSCode Icons” extension (or a similar icon theming setup), you can associate .wll files to use the Welle icon.
Example snippet to add to your VS Code user settings (typically ~/.config/Code/User/settings.json on Linux):
"vsicons.associations.files": [
{
"icon": "welle",
"extensions": ["wll"],
"format": "svg"
}
]Then ensure your icon theme knows where to find the SVG. A simple approach is to copy assets/welle.svg into the icon theme’s custom icons directory (varies by theme), and register "welle" to that SVG.
Icon theme configuration differs across themes; the snippet above is the file-association part.
cmd/welle/— CLI entrypointcmd/welle-lsp/— language server (LSP)internal/— lexer/parser/evaluator/compiler/vm/formatter/linter/LSP internalsstd/— Welle stdlib modulesexamples/— runnable Welle programsdocs/— spec and development notesvscode-welle/— VS Code extension
Issues and PRs are welcome.
- Please include repro steps and expected/actual behavior.
- For language changes, update docs/spec.md when behavior changes.
- Add/adjust tests under
internal/**where appropriate.
GPLv3 (see LICENSE)