Repository navigation
Pepper v0.2.0
Pepper v0.2.0: everything merged since the v0.1.0 extension release (2026-09-21). One line per pull request.
The VS Code extension is published as release vsix-v0.2.0. It was built from main at 543c43c0, which is v0.2.0 plus #275, a test-only fix to the LSP smoke test.
Language
- Attribute syntax
[Name(args)]on functions, blocks, externs, structs and members (#39) - Per-platform code with
OS(...)/Arch(...), consolidated into[Target(<bool expr>)](#40, #46), also on type aliases and module-scope variables (#57) [LinkName("sym")]for externs (#56)- Type aliases (#52)
- Modules: private by default with
export(#53), import/export forms (#54),export * from/export [...] fromre-exports (#138) - Reject C
T*pointer syntax outside extern declarations (#59) i16/u16(short/ushort) (#61)forloops and the iterator protocol (#66)- Function types and named function references (#67), closure literals (#93), methods, constructors and generic functions as values (#96), plain vs
sharedfunction types (#111), named functions and captureless closures as C callbacks (#113) constructreplacesnewconstructors, with deprecation warnings and fixes (#76)withblocks and theScoped<T>protocol (#80)- Weak references:
__weak<T>andWeak<T>(#84) - Traits as types, with dynamic dispatch (#88)
- An extension method needs an import of its file (#91)
- Module-scope variables must be
constand thread-safe (#95) [Deprecated("message")](#104)- Type argument inference, generic methods, iterator
map/filter(#105) [Implicit]constructors (#106)- Overloading: free functions (#119), methods, static methods and operators (#129), extension methods and trait members (#147), constructors (#150)
- Each file outside a module is namespaced by its path (#120)
- A struct may hold a field of its own type (#130)
- Pepper-style operator methods, indexers and constructor parameters (#131)
- Character literals
'a'(#132) - Semicolons are required; line breaks never end a statement (#136), and a missing
;is an error (#158) - Tuples and multiple return values (#140), collections,
==, hashing, labels and nested destructuring (#159), optional and labeled tuples (#160), tuple patterns inmatchandis(#176) T?forOptional<T>(#141)- Unary operator overloads and the truth test
!!(#142) - Enums: value enums and
match(#144), methods,name()andfrom_value()(#154), cases that carry values (#168),matchexpressions,istests and literal patterns (#173) - Float arguments convert to integer parameters (#166)
main(args: String[])(#171)- Array and map literals (#174)
- String interpolation
$"text {name}"withToString(#175), expressions in holes (#192), no assignments in holes (#197) - Generic constraints:
T: Shape & Namedchecked at every use (#202), constrained bodies checked against their constraints (#203), constrained extensions and conditional conformance (#204), the built-inSharedconstraint (#205) - Static methods may call sibling statics by bare name (#235)
Runtime and library
- The runtime is written in Pepper; the C support library is gone (#44)
- Runtime types renamed to PascalCase:
String,Array,HashMap,HashSet(#50); fields and constants follow the naming conventions (#127, #134, #143, #148, #156, #161, #190) Result<TValue, TError=Error>and default generic parameters (#51), later an enum (#177);None(#58);Optional<T>(#133)Atomic<T>and[Link("library")](#49);Atomicmoved into the async module (#200)- The io module:
File,Directory,Path(#62); TCP and UDP sockets (#165); Unix domain sockets (#198); tasks park on file reads and writes (#191) - The async module:
Thread,ThreadId,ThreadLocaland CPU counts (#92);Mutex,Condition,Once,Lazy,Channel(#121); copy andCopyable(#135); confinement andMutex<T>for any struct (#157);move(x),[Move]and thePEP_CHECK_SYNCcensus (#169);Select<E>andCondition.wait_while(#194);TaskLocal<T>(#208) - Tasks: fibers and a scheduler (#178); parking on sockets and
async.timeout(#183); I/O backends chosen at run time, IOCP and poll (#184); several workers andasync.spawn(#185);run_blocking, stream transfer and per-worker accept (#186); tasks park onMutex,Condition,ChannelandThread.sleep(#187); an opt-in io_uring backend (#188) - Runtime API cleanups:
Stringmessages,!==,Result.value,Result<void>(#101) - The runtime uses overloads (#162), character literals (#139) and is formatted with pep-fmt (#179)
arguments()andexit(code)(#163); text helpers,Array.sortand ordered print output (#164)- Format specifications and
String.format(#196) - A
tlsmodule: TLS 1.2/1.3 over TCP (OpenSSL 3, SChannel) (#209) - An
httpmodule: HTTP/1.1 client and server (#210) Uri: RFC 3986 URI references (#240)
Tooling and LSP
- Clang-style compiler errors with exact line and column (#64), documented as the standard (#74)
- The VS Code extension installs from any branch and hot-restarts pepper-lsp (#55)
- Hover and go-to-definition follow imports (#69); implicit conversions shown in hover and inlay hints (#112); pepper-lsp stays alive (nesting limit, CRLF, closure panics, restarts) (#201); go-to-definition hang fixed (#213) and nested members (#253); hover types inferred locals (#259) and shows parameters in scope and an assignment's left side (#266)
- pep-fmt, a formatter written in Pepper, and the tools/syntax library (#124); enums,
match, optionals andformat: offregions (#172); runtime helpers (#181) - The Pepper book and INTERNALS.md (#78); docs kept current per PR (#81); naming conventions (#125); agent rules (#47, #170, #189)
-T timeand deterministic output (#114); speed-ups in sema and parsing (#109, #180, #182, #193)- Build cache: one object per unit with unchanged units reused (#137), units keyed by their sources (#153), cached units' bodies skip sema (#167), keys by their inputs' interfaces with early cutoff (#212)
CI and build
- The VSIX is packaged when GitHub-hosted legs fail (#79)
- Self-hosted runners for Windows and Linux (#65), macOS (#83), and every workflow, with the VSIX built only on release or dispatch (#146); build output and LLVM reused across runs (#77)
- Driver integration tests link into one binary (#115) and compile through the real load path (#71); unique temp directories (#90, #123, #126)
- No CI on pushes to main (#118); incremental compilation off in persistent target dirs (#151); prose-only PRs skip build and test jobs (#155); the LLVM version matrix runs before a release (#206, #211); test threads capped at 16 and cache verification on Linux only (#215);
async.runtest programs run one at a time (#224); no CI on draft PRs (#258) - The vestigial C++ implementation is removed (#48)
- The version is 0.2.0 (#267)
Fixes
returninside nested blocks (#41); ten bugs from edge-case tests (#42); refcount leaks atbreak/continueand ternary (#45); compiler fixes from the io work (#63)assert(x, __null)segfault (#68); chained indexing through pointer elements (#70); struct returns from specialized extensions (#72); an uncalled override of another file's private generic (#73)- Bugs found by the docs audit (#82);
Array.Apirefcounts and the corpus run (#86); compiler warnings (#89) - One scope walker for linking and visibility (#85); each file its own namespace for private names (#87)
- Pointee type inference for
var v = p[i](#94); struct overrides of generic functions across files (#97); raw pointers as struct references and Strings as pointers rejected (#102) - A trait default's bare calls bind only to the trait's methods (#108); calls in a generic struct's methods (#116); string literal bytes to
char/voidpointer slots (#122) - Type-parameter fields zero-initialized with
__default<T>(#145); a store of the wrong LLVM type is an internal error (#149) - Generic calls in generic extensions and trait-value call results (#199); the JIT's sections stay in one region on Windows (#207)
- TLS and socket write bugs (#221); string literals in trait default bodies and operators on implicit-this calls (#251); functions with cached bodies usable as values (#256);
__default<T>()is typed, so a tuple literal can hold it (#268)