This roadmap outlines the implementation plan for SolScript, a high-level language for Solana smart contract development.
| Decision | Choice |
|---|---|
| Implementation Language | Rust |
| Parser | pest (PEG grammar) |
| Compilation Strategy | Hybrid (Rust/Anchor codegen + Direct LLVM BPF) |
| First Target | Full Example contract |
| Package Registry | GitHub (self-hosted) |
| Governance | Open |
| Phase | Status |
|---|---|
| Phase 0: Specification | COMPLETE |
| Phase 1: Core Compiler | COMPLETE |
| Phase 2: Code Generation | COMPLETE |
| Phase 3: CLI & Developer Experience | COMPLETE |
| Phase 4.1: Direct BPF Compilation | COMPLETE |
| Phase 4.2: Language Server (LSP) | COMPLETE (basic) |
| Phase 4.3: Package Manager | Planned |
| Phase 5: Ecosystem | IN PROGRESS |
Status: COMPLETE
The language specification is documented in specs.md with 12 sections covering all language features. See inconsistencies.md for resolved design decisions.
Status: COMPLETE
Status: COMPLETE
Goal: Establish project structure and tokenize SolScript source code.
solscript/
├── Cargo.toml
├── crates/
│ ├── solscript-lexer/ # Tokenization
│ ├── solscript-parser/ # AST generation
│ ├── solscript-ast/ # AST types
│ ├── solscript-typeck/ # Type checking
│ ├── solscript-codegen/ # Rust code generation
│ ├── solscript-bpf/ # Direct LLVM BPF compilation
│ ├── solscript-lsp/ # Language Server Protocol
│ └── solscript-cli/ # CLI tool
├── grammar/
│ └── solscript.pest # PEG grammar
└── examples/
└── *.sol # Example contracts
- Initialize Cargo workspace with crate structure
- Define pest grammar for tokens:
- Keywords (
contract,fn,let,struct,trait,impl, etc.) - Operators (
+,-,*,/,==,!=,&&,||, etc.) - Delimiters (
{,},(,),[,],;,:, etc.) - Literals (integers, strings, booleans, addresses)
- Identifiers
- Comments (single-line
//, multi-line/* */, doc///) - Decorators (
@state,@public,@view, etc.) - Attributes (
#[derive],#[test], etc.)
- Keywords (
- Implement token span tracking for error reporting
- Write lexer tests for all token types
- Can tokenize all examples in
specs.md - Tokens include source location (line, column, span)
- Comprehensive test coverage
Status: COMPLETE
Goal: Parse tokens into an Abstract Syntax Tree.
// Core AST nodes to implement
pub enum Item {
Contract(ContractDef),
Struct(StructDef),
Enum(EnumDef),
Trait(TraitDef),
Impl(ImplBlock),
Function(FnDef),
Event(EventDef),
Error(ErrorDef),
Import(ImportStmt),
Module(ModuleDef),
}
pub enum Stmt {
Let(LetStmt),
Return(ReturnStmt),
If(IfStmt),
Match(MatchStmt),
While(WhileStmt),
For(ForStmt),
Expr(ExprStmt),
Emit(EmitStmt),
}
pub enum Expr {
Literal(Literal),
Ident(Ident),
Binary(BinaryExpr),
Unary(UnaryExpr),
Call(CallExpr),
MethodCall(MethodCallExpr),
FieldAccess(FieldAccessExpr),
Index(IndexExpr),
Struct(StructExpr),
Array(ArrayExpr),
Closure(ClosureExpr),
Await(AwaitExpr),
Try(TryExpr),
Match(MatchExpr),
Block(BlockExpr),
}- Define complete pest grammar for SolScript
- Top-level items (contract, struct, trait, impl, etc.)
- Statements
- Expressions with precedence
- Type annotations
- Generics and constraints
- Patterns for match/let
- Define AST types in
solscript-astcrate - Implement parser that builds AST from pest pairs
- Implement pretty-printer for AST (debugging)
- Error recovery for better error messages
- Write parser tests for all language constructs
- Parses all examples from
specs.mdinto valid AST - Error messages include source location and context
- AST can be pretty-printed back to valid SolScript
Status: COMPLETE
Goal: Resolve all names and build symbol tables.
- Define symbol table structure
- Scopes (global, contract, function, block)
- Symbol types (type, function, variable, field)
- Visibility tracking
- Implement name resolution pass
- Resolve type references
- Resolve function calls
- Resolve variable references
- Handle imports
- Detect undefined/duplicate symbol errors
- Resolve trait implementations to types
- Handle generic type parameters
- All names resolved to their definitions
- Clear errors for undefined/ambiguous names
- Import resolution working
Status: COMPLETE
Goal: Implement full type checking.
pub enum Type {
// Primitives
U8, U16, U32, U64, U128,
I8, I16, I32, I64, I128,
Bool, String, Address,
// Compound
Array(Box<Type>, usize), // [T; N]
Vec(Box<Type>), // Vec<T>
Map(Box<Type>, Box<Type>), // Map<K, V>
Option(Box<Type>), // Option<T>
Result(Box<Type>, Box<Type>), // Result<T, E>
Tuple(Vec<Type>), // (T, U, ...)
// User-defined
Struct(StructId),
Enum(EnumId),
Contract(ContractId),
Trait(TraitId),
// Generics
Generic(GenericParam),
Applied(Box<Type>, Vec<Type>), // T<A, B>
// Special
Unit, // ()
Never, // !
Infer, // _ (to be inferred)
Error, // Type error placeholder
}- Implement type representation
- Implement type inference engine
- Hindley-Milner style inference
- Constraint generation
- Constraint solving
- Type check all expressions
- Type check all statements
- Validate function signatures
- Check trait bounds
- Validate generic instantiations
- Check
Resultand?operator usage - Implement type coercion rules
- Validate decorator usage (
@state,@public, etc.)
- Catches all type errors
- Generic functions/types work correctly
- Trait bounds enforced
- Good error messages for type mismatches
Status: COMPLETE
Goal: Validate program semantics beyond type checking.
- Validate contract structure
- Single
initfunction per contract - State variables have correct decorators
- Public functions are valid entry points
- Single
- Control flow analysis
- All paths return a value
- No unreachable code warnings
- Break/continue in valid contexts
- Mutability checking
-
@viewfunctions don't mutate state - Immutable variable reassignment errors
-
- Ownership/borrowing (simplified)
- No use after move (for non-Copy types)
- Security checks
- Overflow protection annotations
- Signer verification requirements
- Async validation
-
awaitonly inasyncfunctions - Proper CPI context
-
- Catches semantic errors before codegen
- Security issues flagged
- Contract structure validated
Status: COMPLETE
Status: COMPLETE
Goal: Generate valid Rust/Anchor code from SolScript.
// Generated from: counter.ss
use anchor_lang::prelude::*;
declare_id!("...");
#[program]
pub mod counter {
use super::*;
pub fn init(ctx: Context<Init>) -> Result<()> {
// Generated from SolScript init function
Ok(())
}
pub fn increment(ctx: Context<Increment>) -> Result<()> {
// Generated from SolScript public function
ctx.accounts.counter.count += 1;
Ok(())
}
}
#[derive(Accounts)]
pub struct Init<'info> {
// Generated account constraints
}
#[account]
pub struct Counter {
pub count: u64,
}- Generate Rust module structure
- Generate struct definitions
- Generate enum definitions
- Generate function bodies
- Generate Anchor account structs
- Generate Anchor
#[program]module - Map SolScript types to Rust types
- Generate error types
- Generate event emission
- Handle
self→ account access translation
- Generated Rust compiles with
cargo build-sbf - Output is readable and debuggable
- Preserves SolScript semantics
Status: COMPLETE
Goal: Provide SolScript standard library that maps to Anchor/Solana.
-
@solana/token→ SPL Token CPI wrappers -
@solana/account→ Account creation helpers -
@solana/pda→ PDA derivation utilities -
@solana/cpi→ Generic CPI helpers -
@solana/clock→ Clock sysvar access -
@solana/rent→ Rent calculations -
@solana/crypto→ Signature verification
- Standard library imports resolve correctly
- Generated code uses appropriate Solana/Anchor APIs
Status: COMPLETE
Goal: Compile a complete contract using most language features.
// examples/token.ss - Target full example
import { Token } from "@solana/token";
import { PDA } from "@solana/pda";
error InsufficientBalance(available: u64, required: u64);
error Unauthorized;
event Transfer(from: Address, to: Address, amount: u64);
event Mint(to: Address, amount: u64);
#[derive(Clone, Serialize, Deserialize)]
struct TokenMetadata {
name: string;
symbol: string;
decimals: u8;
}
contract TokenContract {
@state totalSupply: u64;
@state balances: Map<Address, u64>;
@state metadata: TokenMetadata;
@state owner: Address;
fn init(name: string, symbol: string, decimals: u8, initialSupply: u64) {
self.metadata = TokenMetadata { name, symbol, decimals };
self.totalSupply = initialSupply;
self.balances.set(tx.sender, initialSupply);
self.owner = tx.sender;
}
@public
fn transfer(to: Address, amount: u64): Result<(), Error> {
let senderBalance = self.balances.get(tx.sender).unwrap_or(0);
if senderBalance < amount {
return Err(InsufficientBalance(senderBalance, amount));
}
self.balances.set(tx.sender, senderBalance - amount);
let recipientBalance = self.balances.get(to).unwrap_or(0);
self.balances.set(to, recipientBalance + amount);
emit Transfer(tx.sender, to, amount);
return Ok(());
}
@public
fn mint(to: Address, amount: u64): Result<(), Error> {
if tx.sender != self.owner {
return Err(Unauthorized);
}
self.totalSupply += amount;
let balance = self.balances.get(to).unwrap_or(0);
self.balances.set(to, balance + amount);
emit Mint(to, amount);
return Ok(());
}
@public
@view
fn balanceOf(account: Address): u64 {
return self.balances.get(account).unwrap_or(0);
}
@public
@view
fn getMetadata(): TokenMetadata {
return self.metadata.clone();
}
}
- Compile full token contract
- Deploy to Solana devnet
- Test all functions via CLI/client
- Verify event emission
- Verify error handling
- Contract deploys and runs on devnet
- All functions work correctly
- Events visible in transaction logs
- Errors returned appropriately
Status: COMPLETE
Status: COMPLETE
Goal: Create the solscript CLI.
solscript init <project-name> # Create new project
solscript build # Compile to Rust/Anchor
solscript build-bpf # Compile to BPF bytecode
solscript build-bpf --llvm # Direct LLVM compilation (fast)
solscript test # Run tests
solscript deploy # Deploy to cluster
solscript verify # Verify deployed program
solscript fmt # Format source code
solscript check # Type check without building
solscript lsp # Start Language Server- Implement
initwith project template - Implement
buildpipeline - Implement
build-bpffor BPF compilation - Implement
checkfor fast feedback - Implement
fmtcode formatter - Configuration via
solscript.toml - Colored error output
- Watch mode for development
Status: COMPLETE
Goal: Enable testing SolScript contracts.
-
#[test]attribute support -
#[should_fail]attribute - Test context/fixture setup
- Assert macros
- Test isolation (BanksClient)
- Coverage reporting (planned)
Status: COMPLETE
Goal: Provide excellent error messages.
error[E0001]: type mismatch
--> src/token.ss:24:12
|
24 | return "hello";
| ^^^^^^^ expected `u64`, found `string`
|
= help: try converting with `.parse::<u64>()?`
error[E0002]: undefined variable
--> src/token.ss:30:5
|
30 | balance = 100;
| ^^^^^^^ not found in this scope
|
= help: did you mean `self.balance`?
- Source snippets in errors
- Colored output
- Suggestions/hints
- Error codes with documentation
- Multi-span errors
Status: COMPLETE
Goal: Skip Rust codegen for faster compilation via direct LLVM-to-BPF compilation.
The direct BPF compilation path uses LLVM 18 with inkwell bindings to generate Solana BPF bytecode directly from the AST, bypassing the Rust/Anchor intermediate step.
Key Components:
solscript-bpfcrate with LLVM feature flag- Type mapping from SolScript types to LLVM types
- Solana syscall intrinsics (sol_log, sol_invoke, PDA derivation, etc.)
- Instruction dispatch with Anchor-compatible discriminators
- BPF-specific function attributes (nounwind, norecurse)
Usage:
# Requires LLVM 18 with BPF target
export LLVM_SYS_180_PREFIX=/usr/lib/llvm-18
cargo build -p solscript-bpf --features llvm
# Compile a contract
solscript build-bpf --llvm my_contract.sol -o target/deploy- LLVM IR generation
- BPF backend integration
- Optimization passes (O0-O3)
- Solana syscall intrinsics
- Entrypoint with instruction dispatch
- Anchor-compatible discriminators
- Debug info generation (planned)
Status: COMPLETE (Basic)
Goal: IDE support via LSP.
- Go to definition
- Find references
- Hover information
- Autocomplete
- Inline errors
- Rename symbol (planned)
- Code actions (planned)
Status: Planned
Goal: Share and reuse SolScript libraries.
- Package manifest format
- GitHub registry integration
- Dependency resolution
- Version constraints
-
solscript add <package>
Status: IN PROGRESS
Status: COMPLETE (Basic)
- Language guide
- API reference
- Tutorials
- Examples gallery
Documentation available at documentation/docs/ using mdBook.
Status: COMPLETE (Basic)
- Syntax highlighting
- LSP integration
- Snippets
- Debugger integration (planned)
Extension available in editors/vscode/.
Status: COMPLETE
- Counter contract (
examples/counter/) - Token contract (
examples/token/) - Simple contract (
examples/simple/) - NFT marketplace (planned)
- DeFi AMM (planned)
- Governance DAO (planned)
Phase 1 (Core Compiler) [COMPLETE]
├── 1.1 Project Setup & Lexer [COMPLETE]
├── 1.2 Parser & AST [COMPLETE]
├── 1.3 Symbol Table [COMPLETE]
├── 1.4 Type System [COMPLETE]
└── 1.5 Semantic Analysis [COMPLETE]
Phase 2 (Code Generation) [COMPLETE]
├── 2.1 Rust Code Generation [COMPLETE]
├── 2.2 Standard Library Stubs [COMPLETE]
└── 2.3 Full Example Contract [COMPLETE]
Phase 3 (Developer Experience) [COMPLETE]
├── 3.1 CLI Tool [COMPLETE]
├── 3.2 Testing Framework [COMPLETE]
└── 3.3 Error Messages [COMPLETE]
Phase 4 (Advanced)
├── 4.1 Direct BPF Compilation [COMPLETE]
├── 4.2 Language Server [COMPLETE - Basic]
└── 4.3 Package Manager [PLANNED]
Phase 5 (Ecosystem) [IN PROGRESS]
├── 5.1 Documentation [COMPLETE - Basic]
├── 5.2 VS Code Extension [COMPLETE - Basic]
└── 5.3 Example Projects [IN PROGRESS]
| Milestone | Criteria | Status |
|---|---|---|
| MVP | Full example contract compiles and deploys to devnet | ACHIEVED |
| Alpha | CLI usable, basic error messages, 3 example contracts | ACHIEVED |
| Beta | LSP working, package manager, comprehensive tests | PARTIAL (LSP done, package manager planned) |
| 1.0 | Production-ready, audited, documented | In Progress |
SolScript supports two compilation modes:
Generates Rust/Anchor code, then uses cargo build-sbf:
solscript build-bpf my_contract.solPros: Well-tested, full Anchor ecosystem support Cons: Slower compilation, requires Rust toolchain
Compiles directly to BPF bytecode via LLVM:
solscript build-bpf --llvm my_contract.solPros: Faster compilation, smaller output Cons: Requires LLVM 18, fewer optimizations
┌─────────────────┐
│ Source Code │
│ (.sol file) │
└────────┬────────┘
│
┌────────▼────────┐
│ Parser │
│ (pest grammar) │
└────────┬────────┘
│
┌────────▼────────┐
│ AST │
│ (solscript-ast) │
└────────┬────────┘
│
┌────────▼────────┐
│ Type Check │
│(solscript-typeck│
└────────┬────────┘
│
┌──────────────┴──────────────┐
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ Anchor Codegen │ │ LLVM Codegen │
│(solscript-codegen) │ (solscript-bpf) │
└────────┬────────┘ └────────┬────────┘
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ Rust/Anchor │ │ LLVM IR │
│ Source │ │ │
└────────┬────────┘ └────────┬────────┘
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ cargo build-sbf │ │ BPF Target │
└────────┬────────┘ └────────┬────────┘
│ │
└──────────────┬──────────────┘
│
┌────────▼────────┐
│ .so Program │
│ (deployable) │
└─────────────────┘
Last updated: January 18, 2026