chore(ffi-linkage): post-stream polish — vscode keywords + vestigial param + extension metadata
Two post-stream follow-ups flagged in CHECKPOINT-EXTERN-EXPORT.md, plus a reproducible vscode-extension packaging setup: - parser: drop the vestigial `RuntimeClassPrefix.is_extern` field and `parseRuntimeClassDecl`'s `is_extern` param. Always false since the `#foreign` token was deleted; the postfix `extern`/`export` keyword is the sole reference-vs-define decider. No behavior change (644 corpus / 442 unit). - vscode grammar: highlight `extern`/`export` as `storage.modifier.sx`. - vscode packaging: declare `@vscode/vsce` as a devDep + add `package` / `vscode:prepublish` scripts so the vsix rebuilds reproducibly (was an ambient tool). Add repository/homepage/bugs (Gitea), icon (swipelab logo, 256x256), galleryBanner, README with cover banner. Rebuilt the vsix.
This commit is contained in:
@@ -355,11 +355,13 @@ AOT), 1227 (export fn rename, AOT), 1348 (objc extern class), 1349 (objc export
|
||||
`#foreign`; the keyword is rejected; zero `foreign` remains in the gated tree (Parts
|
||||
A + B, Phases 0–9 all done; the 9.4 gate passes). This stream can be archived.
|
||||
|
||||
Possible follow-ups (NOT required, NOT this stream):
|
||||
- Optionally add `extern`/`export` to the editors/vscode tmLanguage keyword list (the
|
||||
`#foreign` directive was removed; the new keywords aren't specially highlighted yet).
|
||||
- The `RuntimeClassPrefix.is_extern` field + `parseRuntimeClassDecl`'s `is_extern`
|
||||
param are now vestigial (always false post-token-deletion) — a cosmetic cleanup.
|
||||
Follow-ups (both DONE 2026-06-15, post-stream polish):
|
||||
- ✅ Added `extern`/`export` to the editors/vscode tmLanguage keyword list as a
|
||||
`storage.modifier.sx` pattern (`editors/vscode/syntaxes/sx.tmLanguage.json`).
|
||||
- ✅ Dropped the vestigial `RuntimeClassPrefix.is_extern` field +
|
||||
`parseRuntimeClassDecl`'s `is_extern` param (always-false dead path; the postfix
|
||||
`extern`/`export` keyword is the sole reference-vs-define decider). Suite green
|
||||
(644 corpus / 442 unit, 0 failed).
|
||||
|
||||
--- (historical: the finish-Phase-9 plan, now done) ---
|
||||
**PART B — finish Phase 9: example FILENAME renames + `issues/*.md` + 9.0/9.4.**
|
||||
|
||||
25
editors/vscode/README.md
Normal file
25
editors/vscode/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||

|
||||
|
||||
# sx for Visual Studio Code
|
||||
|
||||
Language support for the [sx programming language](https://git.swipelab.com/lab/sx).
|
||||
|
||||
## Features
|
||||
|
||||
- **Syntax highlighting** for `.sx` files, including embedded GLSL, SQL, HTML, and JSON blocks.
|
||||
- **Language server integration** — the extension launches the `sx` binary's language server (`sx lsp`) to provide editor intelligence.
|
||||
- **Breakpoints** registered for the `sx` language.
|
||||
|
||||
## Requirements
|
||||
|
||||
The `sx` compiler must be installed and on your `PATH` (or point the extension at it via the setting below). The extension shells out to it for the language server.
|
||||
|
||||
## Settings
|
||||
|
||||
| Setting | Default | Description |
|
||||
|---------|---------|-------------|
|
||||
| `sx.lspPath` | `sx` | Path to the `sx` binary used to start the language server (`sx lsp`). |
|
||||
|
||||
## License
|
||||
|
||||
See the repository for license details.
|
||||
BIN
editors/vscode/cover.png
Normal file
BIN
editors/vscode/cover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
BIN
editors/vscode/icon.png
Normal file
BIN
editors/vscode/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
3818
editors/vscode/package-lock.json
generated
3818
editors/vscode/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,19 @@
|
||||
"description": "Language support for the sx programming language",
|
||||
"version": "0.0.1",
|
||||
"publisher": "swipelab",
|
||||
"icon": "icon.png",
|
||||
"galleryBanner": {
|
||||
"color": "#000000",
|
||||
"theme": "dark"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.swipelab.com/lab/sx.git"
|
||||
},
|
||||
"homepage": "https://git.swipelab.com/lab/sx",
|
||||
"bugs": {
|
||||
"url": "https://git.swipelab.com/lab/sx/issues"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.75.0"
|
||||
},
|
||||
@@ -73,13 +86,16 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p .",
|
||||
"watch": "tsc -watch -p ."
|
||||
"watch": "tsc -watch -p .",
|
||||
"vscode:prepublish": "npm run build",
|
||||
"package": "vsce package --baseContentUrl https://git.swipelab.com/lab/sx/src/branch/master/editors/vscode --baseImagesUrl https://git.swipelab.com/lab/sx/raw/branch/master/editors/vscode"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^9.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/vscode": "^1.75.0",
|
||||
"@vscode/vsce": "^3.9.2",
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -193,6 +193,10 @@
|
||||
"name": "keyword.other.sx",
|
||||
"match": "\\b(enum|struct)\\b"
|
||||
},
|
||||
{
|
||||
"name": "storage.modifier.sx",
|
||||
"match": "\\b(extern|export)\\b"
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.cast.sx",
|
||||
"match": "\\bxx\\b"
|
||||
|
||||
@@ -258,7 +258,7 @@ pub const Parser = struct {
|
||||
// Postfix `extern` flips that to "reference an existing class on the runtime
|
||||
// side". `#jni_main` flags the class as the launchable entry (Android Activity).
|
||||
if (self.tryParseRuntimeClassPrefix()) |prefix| {
|
||||
return self.parseRuntimeClassDecl(name, start_pos, prefix.runtime, prefix.is_extern, prefix.is_main, name_is_raw);
|
||||
return self.parseRuntimeClassDecl(name, start_pos, prefix.runtime, prefix.is_main, name_is_raw);
|
||||
}
|
||||
|
||||
// C-style union declaration
|
||||
@@ -1273,7 +1273,6 @@ pub const Parser = struct {
|
||||
|
||||
const RuntimeClassPrefix = struct {
|
||||
runtime: ast.RuntimeKind,
|
||||
is_extern: bool,
|
||||
is_main: bool,
|
||||
};
|
||||
|
||||
@@ -1285,11 +1284,9 @@ pub const Parser = struct {
|
||||
/// state untouched.
|
||||
fn tryParseRuntimeClassPrefix(self: *Parser) ?RuntimeClassPrefix {
|
||||
// Peek ahead through the optional `#jni_main` modifier to confirm a
|
||||
// runtime-class directive follows. (`is_extern` — reference vs define —
|
||||
// is decided by the POSTFIX `extern`/`export` keyword in parseRuntimeClassDecl,
|
||||
// never a prefix; it stays false here.)
|
||||
// runtime-class directive follows. (reference vs define is decided by the
|
||||
// POSTFIX `extern`/`export` keyword in parseRuntimeClassDecl, never a prefix.)
|
||||
var lookahead_idx: usize = 0;
|
||||
const is_extern = false;
|
||||
var is_main = false;
|
||||
while (true) {
|
||||
const tag = self.peekTag(lookahead_idx);
|
||||
@@ -1305,7 +1302,7 @@ pub const Parser = struct {
|
||||
// Commit: consume modifier tokens.
|
||||
var i: usize = 0;
|
||||
while (i < lookahead_idx) : (i += 1) self.advance();
|
||||
return .{ .runtime = runtime, .is_extern = is_extern, .is_main = is_main };
|
||||
return .{ .runtime = runtime, .is_main = is_main };
|
||||
}
|
||||
|
||||
fn peekTag(self: *Parser, offset: usize) Tag {
|
||||
@@ -1340,7 +1337,7 @@ pub const Parser = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn parseRuntimeClassDecl(self: *Parser, name: []const u8, start_pos: u32, runtime: ast.RuntimeKind, is_extern: bool, is_main: bool, name_is_raw: bool) anyerror!*Node {
|
||||
fn parseRuntimeClassDecl(self: *Parser, name: []const u8, start_pos: u32, runtime: ast.RuntimeKind, is_main: bool, name_is_raw: bool) anyerror!*Node {
|
||||
self.advance(); // skip directive token
|
||||
|
||||
try self.expect(.l_paren);
|
||||
@@ -1356,10 +1353,8 @@ pub const Parser = struct {
|
||||
// directive (mirrors `struct #compiler` postfix placement):
|
||||
// `… extern { … }` ⇒ reference an existing runtime class.
|
||||
// `… export { … }` ⇒ define + register a new sx class (the default).
|
||||
// Maps onto `is_extern`, threaded into the runtime_class_decl node. (The
|
||||
// passed `is_extern` is always false here — the removed prefix linkage
|
||||
// form is rejected by the caller before this point.)
|
||||
var is_extern_eff = is_extern;
|
||||
// Maps onto `is_extern`, threaded into the runtime_class_decl node.
|
||||
var is_extern_eff = false;
|
||||
if (self.current.tag == .kw_extern or self.current.tag == .kw_export) {
|
||||
is_extern_eff = self.current.tag == .kw_extern;
|
||||
self.advance();
|
||||
|
||||
Reference in New Issue
Block a user