{"id":50276876,"url":"https://github.com/mysbryce/doublemint","last_synced_at":"2026-05-27T21:02:37.333Z","repository":{"id":360499527,"uuid":"1250403407","full_name":"mysbryce/doublemint","owner":"mysbryce","description":"doublemint - c++ transpiler (Typescript-like)","archived":false,"fork":false,"pushed_at":"2026-05-26T16:37:42.000Z","size":3472,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-26T18:19:39.543Z","etag":null,"topics":["cpp","dlm","doublemint","gcc","javascript","native","transplier","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mysbryce.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-26T15:41:20.000Z","updated_at":"2026-05-26T16:37:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mysbryce/doublemint","commit_stats":null,"previous_names":["mysbryce/doublemint"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mysbryce/doublemint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysbryce%2Fdoublemint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysbryce%2Fdoublemint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysbryce%2Fdoublemint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysbryce%2Fdoublemint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mysbryce","download_url":"https://codeload.github.com/mysbryce/doublemint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysbryce%2Fdoublemint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33583399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","dlm","doublemint","gcc","javascript","native","transplier","typescript"],"created_at":"2026-05-27T21:02:35.403Z","updated_at":"2026-05-27T21:02:37.324Z","avatar_url":"https://github.com/mysbryce.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Doublemint\n\nDoublemint is a production-oriented `.dlm` → C++20 transpiler. It pairs TypeScript-style ergonomics with a curated runtime (vendored uWebSockets / libuv, SQLite, crypto helpers, JSON / schema, etc.) so a Mint program can build a HTTP server, talk to a database, or drive a native subprocess without writing FFI glue.\n\nThe version line is `0.0.1-dev-N` — each `N` corresponds to one shipped feature plus its patch note in [`patch-notes/`](patch-notes).\n\n## Pipeline\n\n1. Scan `.dlm` source into tokens.\n2. Parse a typed AST with a hand-written recursive-descent parser.\n3. Resolve the strict multi-file module graph, including builtin `mint:*` imports.\n4. Run semantic checks (types, generics, mutation, exhaustiveness).\n5. Emit `.hpp` + `.cpp` per module, including any vendored runtime sources the program uses.\n6. Compile a native binary (gcc for `.c` → `.o`, g++ for `.cpp` → `.o`, g++ for the link). On Windows MinGW the linker auto-falls-back to a direct collect2 invocation with `COMPILER_PATH` / `LIBRARY_PATH` stripped, which dodges the silent exit-5 bug.\n\n## Install\n\n```bash\npnpm install\npnpm build\n```\n\nThe package exposes a `doublemint` binary from `dist/cli.js`.\n\nDuring local development:\n\n```bash\npnpm dev check examples/main.dlm\n```\n\nAfter build:\n\n```bash\nnode dist/cli.js check examples/main.dlm\n```\n\n## Commands\n\n```bash\ndoublemint check \u003centry.dlm\u003e             # lex / parse / resolve / semantic only\ndoublemint check --stdin-filepath \u003cp\u003e    # check unsaved source from stdin\ndoublemint emit \u003centry.dlm\u003e              # write .hpp / .cpp into outDir\ndoublemint build \u003centry.dlm\u003e --out \u003cbin\u003e # emit + invoke the native compiler\ndoublemint fmt \u003centry.dlm\u003e [--write | --check]\ndoublemint repl                          # interactive evaluator (per-line compile)\ndoublemint init [dir]                    # scaffold a hello-world project\ndoublemint info                          # list every mint:* builtin module\ndoublemint version                       # print the current version\n```\n\n`build` flags: `--compiler g++|clang++`, `--cpp-out \u003cdir\u003e`, `--out \u003cbinary\u003e`. The configured compiler is tried first; missing → falls back to `clang++`, `g++`, then `c++`.\n\nBuild the bundled multi-file sample:\n\n```bash\nnode dist/cli.js build examples/player/main.dlm --out build/player/app.exe\n```\n\nBuild the language-tour sample (covers every supported syntax piece in one file):\n\n```bash\nnode dist/cli.js build examples/language_tour/main.dlm --out build/language-tour/app.exe\n```\n\n## Config\n\n`doublemint.config.json` (optional):\n\n```json\n{\n  \"rootDir\": \"src\",\n  \"outDir\": \"build/doublemint\",\n  \"cppStandard\": \"c++20\",\n  \"compiler\": \"g++\",\n  \"includeDirs\": [],\n  \"nativeSources\": [],\n  \"libraryDirs\": [],\n  \"linkLibraries\": [],\n  \"linkerFlags\": [],\n  \"warningsAsErrors\": true,\n  \"optimization\": \"O3\"\n}\n```\n\n## Language Surface\n\nSupported (through `0.0.1-dev-40`):\n\n- **Bindings**: `let` (mutable), `const` (immutable), `constexpr`.\n- **Types**: `int`, `int64`, `float`, `double`, `string`, `bool`, `char`, `Array\u003cT\u003e`, tuples, `Optional\u003cT\u003e`, `T1 | T2 | …` unions, `Future\u003cT\u003e`, plus user-defined `struct`, `enum`, `type` aliases.\n- **Functions**: named functions with typed params + return, `async function` (returns `Future\u003cT\u003e`), generic free functions with inference, `extern` blocks for C/C++ interop, lambdas (single-expression and block bodies).\n- **Statements**: `if`/`else`, `while`, C-style `for`, `for (let x of arr)` and `for (let [a, b] of pairs)` range loops, `switch`/`case`/`default`, `match` (guards allowed) / `_`, `try`/`catch`/`throw`, `defer`, `return`, tuple destructuring (`let [a, b] = expr;`).\n- **Expressions**: arithmetic `+ - * / %`, comparisons `== != \u003c \u003c= \u003e \u003e=`, logical `\u0026\u0026 ||`, unary `- ! ~`, prefix + postfix `++ --`, bitwise `\u0026 | ^ \u003c\u003c \u003e\u003e`, compound assignment (`+= -= *= /= %= \u0026= |= ^= \u003c\u003c= \u003e\u003e=`), ternary `a ? b : c`, match expressions, template literals (`` `hello ${name}` ``), string concat with `+`, member access, indexing, `as` casts, `copy`, `new T(…)`, `await expr`.\n- **Numeric literals**: `1_000_000`, `0xFF`, `0o755`, `0b1010` plus the standard decimal / float forms.\n- **Method-style on primitives**: any `mint:*` namespace function whose first parameter unifies with the receiver becomes a method (`name.upper()` ≡ `String.upper(name)`); numeric and bool primitives also have a built-in `.toString()` without needing an import.\n\nRun `doublemint info` to enumerate the active stdlib modules at any time. The current set:\n\n```\nmint:array      mint:async       mint:base64      mint:collections\nmint:crypto     mint:db          mint:fmt         mint:fs\nmint:http       mint:io          mint:json        mint:log\nmint:math       mint:memory      mint:net         mint:os\nmint:process    mint:regex       mint:schema      mint:simd\nmint:sql        mint:string      mint:term        mint:test\nmint:time\n```\n\n## A Tour\n\n```mint\nimport { println } from \"mint:io\";\nimport { String } from \"mint:string\";\n\nenum Day { Mon, Tue, Wed }\n\nstruct Profile {\n  id: int;\n  name: string;\n  level: int;\n}\n\nasync function fetchLevel(id: int): int {\n  return id * 10;\n}\n\nfunction label(d: Day): string {\n  return match (d) {\n    Day.Mon =\u003e \"monday\",\n    Day.Tue =\u003e \"tuesday\",\n    _ =\u003e \"wednesday\"\n  };\n}\n\nexport function main(): void {\n  let profile: Profile = Profile { id: 1, name: \"mint\", level: 0 };\n  profile.level = await fetchLevel(profile.id);\n\n  println(\"hello \" + profile.name.upper());\n  println(\"day = \" + label(Day.Tue));\n  println(\"level = \" + profile.level.toString());\n\n  let acc: int = 0;\n  for (let i: int = 1; i \u003c= profile.level; i++) {\n    acc += i;\n  }\n  println(\"acc = \" + acc.toString());\n}\n```\n\n## VS Code\n\nSyntax highlighting, autocomplete, hover, go-to-definition, and realtime diagnostics live in [`ext/doublemint-vscode`](ext/doublemint-vscode). Diagnostics call `doublemint check --stdin-filepath` with the current editor buffer.\n\nFor development:\n\n```bash\ncode ext/doublemint-vscode\n```\n\nPress `F5`, then open a `.dlm` file in the Extension Development Host.\n\nPack a VSIX with the latest compiler CLI bundled:\n\n```bash\npnpm pack:vsix\n```\n\n## Native C/C++ Interop\n\nCall simple C/C++ free functions through `extern \"header\"`:\n\n```mint\nextern \"cmath\" {\n  function sqrt(num: double): double;\n}\n```\n\nOpaque types, pointer / reference signatures, local includes, and explicit native symbol aliases all work:\n\n```mint\nextern \"./native.hpp\" {\n  type FILE;\n  function puts_alias(text: const char*): int as \"std::puts\";\n  function close_ref(file: FILE\u0026): int as \"native_close\";\n}\n```\n\n`null` emits to `nullptr` for native pointer handles, and `defer` runs cleanup at scope exit:\n\n```mint\nlet file: FILE* = fopen(\"data.txt\", \"r\");\ndefer fclose(file);\n```\n\nLocal native `.c` / `.cpp` files can be linked into the final binary via `nativeSources`:\n\n```json\n{\n  \"includeDirs\": [\"native\"],\n  \"nativeSources\": [\"native/native_math.cpp\"]\n}\n```\n\n## Diagnostics\n\nEvery error implements `DoublemintDiagnostic` — code, severity, file, line, column, source excerpt, caret, and an optional fix hint:\n\n```text\nERROR DLM2032: Expected ':' after let variable name.\n --\u003e main.dlm:2:9\n  |   let x = 1;\n  |         ^\n```\n\n## Verification\n\nRun the full bar before every release:\n\n```bash\npnpm check            # type-check the TS toolchain\npnpm test             # unit + integration suite (vitest)\npnpm build            # bundle CLI + extension assets\npnpm build:examples   # build every example end-to-end\n```\n\nA bump is not shipped until tests are green and every example builds.\n\n## Release Discipline\n\n1. `pnpm version:bump \"\u003ctitle\u003e\"` bumps `dev-N` and stubs `patch-notes/0.0.1-dev-N.md`.\n2. Implement the feature with at least one integration test.\n3. `pnpm test` + `pnpm build:examples` must pass.\n4. Fill in the patch note (Highlights / Files touched / Tests / examples / Up next).\n5. Commit as `chore(release): 0.0.1-dev-N — \u003ctitle\u003e`.\n\n## Current Limits\n\nDeferred (will land when the surface stabilises):\n\n- classes with methods, traits, or virtual dispatch\n- generic structs / classes (only generic free functions today)\n- enum payload variants + pattern bindings (`Some(x) =\u003e x`)\n- `Result\u003cT, E\u003e` sum type + error propagation operator\n- HTTPS via vendored OpenSSL\n- package registry + version pinning\n- CMake project generation\n- LSP server (beyond `doublemint check --json`)\n\n## Documentation\n\nThe browsable docs (VitePress) live in [`docs/`](docs) — six sections\norganised by audience:\n\n1. **Get Started** — install, quickstart, project layout, editor.\n2. **Core \u0026 Transpiler** — pipeline, type system, module resolver,\n   checker, emitter, native compiler, diagnostics, config.\n3. **Language** — syntax, operators, pattern matching, async, lambdas /\n   generics, structs / enums, native interop.\n4. **CLI** — every `doublemint` command and flag.\n5. **Standard Library** — every `mint:*` module, grouped by domain.\n6. **Releases** — patch notes and roadmap.\n\n```bash\npnpm docs:dev      # http://localhost:5173\npnpm docs:build    # static site → docs/.vitepress/dist\npnpm docs:preview  # serve the built site locally\n```\n\nSee also [`PRODUCT_SPEC.md`](PRODUCT_SPEC.md) for product direction and\n[`CLAUDE.md`](CLAUDE.md) for the contributor playbook (release\ndiscipline, file map, when to update docs).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmysbryce%2Fdoublemint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmysbryce%2Fdoublemint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmysbryce%2Fdoublemint/lists"}