Skip to content

lollipopkit/lk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

198 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

English | 简体中文

LK

a lightweight, efficient, modern language written in Rust

Features

  • Rust-inspired syntax with first-class named parameters
  • Go-style concurrency: go statements spawn true-parallel goroutines (isolate semantics — no data races by construction), blocking channels, and select
  • Swift-style error handling: errors raise and are caught with try/catch; postfix ! force-unwraps nil
  • Rust-shaped macro_rules! declarative macros with function-like calls, explicit macro exports/re-exports, file/package imports, standard macros imports, item attributes, built-in #[derive(Debug|Show)], isolated external derive/attribute/function-like providers, dependency-aware proc macro cache invalidation, LSP macro-origin hover/symbols plus same-file/imported macro and generated item goto-definition, and token-level macro origin/source-map inspection
  • VM interpreter and LLVM compiler backend, supporting cross-platform native compilation and browser WASM
  • Built-in standard library and syntax sugar
  • Package manager and REPL, with VS Code LSP extension support

A Taste

use task;
use chan as ch;

// Goroutines + channels (Go-style, but isolate: crossing values are
// deep-copied — no shared mutable state, no data races by construction).
fn producer(c, n) {
    for i in 0..n {
        send(c, i * i);
    }
    ch.close(c);
}

let c = chan(4);
go producer(c, 5);

// Errors raise; try/catch is the error-handling surface (Swift-style).
let total = 0;
try {
    while (true) {
        total += recv(c);        // raises once c is closed and drained
    }
} catch e {
    // drained: 0 + 1 + 4 + 9 + 16
}

// select multiplexes channels; postfix `!` force-unwraps nil.
let done = chan(1);
send(done, "ok");
let status = select {
    case v <- recv(done) => v;
    default => "pending";
};
let m = {"total": total};
println("{} (total: {})", status, m["total"]!);   // ok (total: 30)

See docs/concurrency.md and docs/semantics.md for the full semantics.

Examples

Details: lang.lollipopkit.com.

Installation

Install the latest GitHub release:

curl -fsSL https://raw.githubusercontent.com/lollipopkit/lk/main/scripts/install.sh | sh

Install a specific release:

curl -fsSL https://raw.githubusercontent.com/lollipopkit/lk/main/scripts/install.sh | LK_VERSION=v0.1.3 sh

Example Files

examples/
├── syntax/          # Language feature demos
│   ├── closure.lk        # Closures & higher-order functions
│   ├── match.lk          # Match expressions and patterns
│   ├── pattern_matching.lk # if-let, while-let, destructuring
│   ├── ...               # More
├── stdlib/           # Standard library demos
│   ├── list_ops.lk        # List methods (map, filter, reduce)
│   ├── stream_demo.lk     # Lazy stream pipelines
│   ├── ...               # More
├── general/          # Practical examples
│   ├── sort_search.lk    # Insertion sort and search algorithms
│   ├── config_parser.lk  # JSON/YAML/TOML config loading
│   ├── ...
└── _references/      # Cross-language references (Dart, Lua, C)

Run any example: lk examples/syntax/closure.lk

Usage

Integration (library)

use lk_core::{syntax::{parse_program_source, ParseOptions}, vm::VmContext};

// Parse and execute through the bytecode VM.
let source = r#"
let data = {
    "req": { "user": { "name": "foo" } },
    "files": [ { "name": "file1", "published": true } ],
};
return data.req.user.name in "foobar" && data.files.0.published == true;
"#;
let program = parse_program_source(source, ParseOptions::default())?;
let mut ctx = VmContext::new();
let result = program.execute_with_ctx(&mut ctx)?;

assert_eq!(result.display_first_return(), "true");

CLI

  • Run REPL: lk
  • Execute a source file or module artifact: lk FILE (supports .lk and .lkm)
  • Type-check without executing: lk check FILE (reports compile-time diagnostics)
  • Compile to a native executable: lk compile [FILE] (omitting FILE uses ./main.lk, package ./src/main.lk, or a single workspace app entry; unsupported LLVM-native shapes fall back to the Tier 0 VM bundle)
  • Compile to a bytecode module artifact: lk compile bytecode [FILE]FILE.lkm
  • Compile to LLVM IR: lk compile llvm [FILE]
  • Create packages and manage decentralized git + lockfile dependencies (no central registry): lk pkg init, lk pkg add, lk pkg fetch, lk pkg update, lk pkg check, lk pkg tree (see docs/packages.md)

Note: command-line argument paths must be sanitized relative paths.

Editor Support

Editor integrations live under ecosystem/.

  • VS Code support is a single merged extension under ecosystem/vsc-ext/lsp. It includes .lk language registration, TextMate highlighting, snippets, and the LK LSP client with smart completion for stdlib modules, imported aliases, local symbols, named arguments, repeated string argument values, and common receiver methods. Use make debug-lsp-ext for a local Extension Development Host, or make vsix to build the VSIX.
  • Zed support lives under ecosystem/zed-ext. It uses ecosystem/tree-sitter-lk for Tree-sitter highlighting and starts lk-lsp for diagnostics, completion, hover, goto definition, document symbols, semantic tokens, and inlay hints. Use make zed-ext-check to validate the extension crate.

License

Apache-2.0 lollipopkit

Acknowledgements

  • Part of the design inspiration came from a handwritten Lua VM/compiler tutorial I read during college.
  • Six months of ChatGPT Pro provided through OpenAI OSS.

About

a lightweight, efficient, modern language written in Rust

Topics

Resources

License

Stars

14 stars

Watchers

3 watching

Forks

Packages

 
 
 

Contributors