From 5ced950380d91bb90c44832aa63537e1e4d03077 Mon Sep 17 00:00:00 2001 From: bad-antics Date: Thu, 23 Apr 2026 16:43:59 -0700 Subject: [PATCH] Add support for Lateralus Adds a Prism component for the Lateralus language (ltl, lat): - components/prism-lateralus.js covering keywords, built-in types, constants, nested block comments, doc comments, raw and byte strings, interpolated strings, typed numeric literals with underscore separators, attribute decorators (#[caps(io, net)]), module paths (foo::bar), lifetimes, and the pipeline operator |>. - tests/languages/lateralus/ with 7 feature tests. - examples/prism-lateralus.html. - components.json entry with aliases 'ltl' and 'lat'. - Regenerated autoloader and show-language aliases. Lateralus is a capability-aware systems language from https://github.com/bad-antics/lateralus-lang. --- components.json | 5 + components/prism-lateralus.js | 109 ++++++++++++++++++ examples/prism-lateralus.html | 61 ++++++++++ plugins/autoloader/prism-autoloader.js | 2 + plugins/show-language/prism-show-language.js | 2 + .../lateralus/attribute_feature.test | 35 ++++++ .../lateralus/builtin-type_feature.test | 56 +++++++++ .../languages/lateralus/comment_feature.test | 18 +++ .../languages/lateralus/keyword_feature.test | 76 ++++++++++++ tests/languages/lateralus/number_feature.test | 32 +++++ .../languages/lateralus/operator_feature.test | 54 +++++++++ tests/languages/lateralus/string_feature.test | 36 ++++++ 12 files changed, 486 insertions(+) create mode 100644 components/prism-lateralus.js create mode 100644 examples/prism-lateralus.html create mode 100644 tests/languages/lateralus/attribute_feature.test create mode 100644 tests/languages/lateralus/builtin-type_feature.test create mode 100644 tests/languages/lateralus/comment_feature.test create mode 100644 tests/languages/lateralus/keyword_feature.test create mode 100644 tests/languages/lateralus/number_feature.test create mode 100644 tests/languages/lateralus/operator_feature.test create mode 100644 tests/languages/lateralus/string_feature.test diff --git a/components.json b/components.json index b353778e90..5f62058e7d 100644 --- a/components.json +++ b/components.json @@ -826,6 +826,11 @@ "title": "Kusto", "owner": "RunDevelopment" }, + "lateralus": { + "title": "Lateralus", + "alias": ["ltl", "lat"], + "owner": "bad-antics" + }, "latex": { "title": "LaTeX", "alias": ["tex", "context"], diff --git a/components/prism-lateralus.js b/components/prism-lateralus.js new file mode 100644 index 0000000000..6e919d1470 --- /dev/null +++ b/components/prism-lateralus.js @@ -0,0 +1,109 @@ +(function (Prism) { + + Prism.languages.lateralus = { + 'comment': [ + { + // nested block comments /* ... /* ... */ ... */ + pattern: /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|\/\*(?:[^*/]|\*(?!\/)|\/(?!\*))*\*\/)*\*\//, + greedy: true + }, + { + pattern: /\/\/\/.*/, + alias: 'doc-comment', + greedy: true + }, + { + pattern: /\/\/.*/, + greedy: true + } + ], + 'string': [ + { + // raw strings: r"..." and r#"..."#, r##"..."## + pattern: /b?r(#*)"(?:\\.|(?!"\1)[^\\])*"\1/, + greedy: true, + alias: 'raw-string' + }, + { + // byte string b"..." + pattern: /b"(?:\\.|[^"\\\r\n])*"/, + greedy: true + }, + { + // regular / interpolated strings + pattern: /"(?:\\.|[^"\\\r\n])*"/, + greedy: true, + inside: { + 'interpolation': { + pattern: /\{[^{}]*\}/, + inside: { + 'interpolation-punctuation': { + pattern: /^\{|\}$/, + alias: 'punctuation' + }, + rest: null // filled below + } + } + } + } + ], + 'char': { + // 'a', '\n', '\u{1F600}', b'x' + pattern: /b?'(?:\\(?:x[0-9a-fA-F]{2}|u\{[0-9a-fA-F]{1,6}\}|.)|[^'\\\r\n])'/, + greedy: true + }, + 'attribute': { + // #[caps(io, net)], @decorator + pattern: /#!?\[[^\]\r\n]*\]|@[a-zA-Z_]\w*/, + alias: 'attr-name', + inside: { + 'punctuation': /^#!?\[|\]$|^@/, + 'string': { + pattern: /"(?:\\.|[^"\\\r\n])*"/, + greedy: true + } + } + }, + 'keyword': /\b(?:actor|as|async|await|break|capability|case|class|const|continue|defer|do|effect|else|enum|export|extern|fn|for|handle|if|impl|import|in|interface|let|loop|match|module|move|mut|of|pub|return|self|spawn|static|struct|super|switch|trait|type|union|unsafe|use|var|when|where|while|with|yield)\b/, + 'builtin-type': { + pattern: /\b(?:Any|Arc|Array|Box|HashMap|HashSet|List|Map|Option|Rc|Ref|RefMut|Result|Set|Slice|Tuple|Vec|bool|byte|bytes|char|f128|f16|f32|f64|i128|i16|i32|i64|i8|isize|never|str|string|u128|u16|u32|u64|u8|usize|void)\b/, + alias: 'keyword' + }, + 'constant': /\b(?:Err|None|Ok|Self|Some|false|nil|true)\b/, + 'class-name': [ + // Type after : or -> or in struct/enum/trait/type/impl declarations + { + pattern: /\b(?:actor|class|enum|impl|interface|struct|trait|type|union)\s+(?!\d)[A-Z]\w*/, + inside: { + 'keyword': /^\w+/ + } + }, + { + // PascalCase identifiers and module paths Foo::Bar + pattern: /\b[A-Z]\w*(?:::[A-Z]\w*)*\b/ + } + ], + 'function': { + pattern: /\b(?!\d)\w+(?=\s*(?:::\s*<|\())/, + greedy: true + }, + 'macro': { + pattern: /\b(?!\d)\w+!(?=\s*[({\[])/, + alias: 'property' + }, + 'lifetime': { + pattern: /'(?!(?:\\(?:x[0-9a-fA-F]{2}|u\{[0-9a-fA-F]{1,6}\}|.)|[^'\\\r\n])')(?!\d)\w+/, + alias: 'symbol' + }, + 'number': /\b(?:0x[a-fA-F0-9](?:_?[a-fA-F0-9])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?)(?:_?(?:f(?:16|32|64|128)|i(?:8|16|32|64|128|size)|u(?:8|16|32|64|128|size)))?\b/, + 'operator': /\|>|->|=>|<-|::|\.\.=?|[!=<>]=|&&|\|\||<<=?|>>=?|[-+*/%&|^!=<>?~]=?/, + 'punctuation': /[{}[\];(),.:@]/ + }; + + // Fill self-referential string interpolation + Prism.languages.lateralus['string'][2].inside['interpolation'].inside.rest = Prism.languages.lateralus; + + Prism.languages.ltl = Prism.languages.lateralus; + Prism.languages.lat = Prism.languages.lateralus; + +}(Prism)); diff --git a/examples/prism-lateralus.html b/examples/prism-lateralus.html new file mode 100644 index 0000000000..9ddfa030f8 --- /dev/null +++ b/examples/prism-lateralus.html @@ -0,0 +1,61 @@ +

Comments

+
// single-line
+/// doc comment
+/* block
+   /* nested */
+   still a comment */
+ +

Strings

+
let s = "hello, {name}!"
+let raw = r"C:\path\to\file"
+let multi = r#"quotes "inside" are fine"#
+let bytes = b"\x00\xFF"
+ +

Numbers

+
let a: u64 = 42_u64
+let b = 0xFF_i32
+let c = 0b1010_1100
+let d = 3.14_f32
+let e = 1_000_000
+ +

Functions and pipelines

+
#[caps(io, net)]
+@inline
+fn fibonacci(n: u64) -> u64 {
+    if n < 2 { return n }
+    fibonacci(n - 1) + fibonacci(n - 2)
+}
+
+pub fn main() -> Result {
+    let xs = [1, 2, 3, 4]
+    xs |> map(fibonacci) |> sum()
+}
+ +

Types, enums, and traits

+
enum Shape {
+    Circle(f64),
+    Rect { w: f64, h: f64 },
+}
+
+trait Area {
+    fn area(self) -> f64
+}
+
+impl Area for Shape {
+    fn area(self) -> f64 {
+        match self {
+            Shape::Circle(r) => 3.14159 * r * r,
+            Shape::Rect { w, h } => w * h,
+        }
+    }
+}
+ +

Actors and capabilities

+
actor Logger {
+    let mut buffer: Vec<string> = []
+
+    #[caps(io)]
+    fn log(msg: str) {
+        self.buffer.push(msg)
+    }
+}
diff --git a/plugins/autoloader/prism-autoloader.js b/plugins/autoloader/prism-autoloader.js index 2881b2d899..f1d0c1c568 100644 --- a/plugins/autoloader/prism-autoloader.js +++ b/plugins/autoloader/prism-autoloader.js @@ -226,6 +226,8 @@ "kt": "kotlin", "kts": "kotlin", "kum": "kumir", + "ltl": "lateralus", + "lat": "lateralus", "tex": "latex", "context": "latex", "ly": "lilypond", diff --git a/plugins/show-language/prism-show-language.js b/plugins/show-language/prism-show-language.js index 6f28a8ef2b..06cb13f568 100644 --- a/plugins/show-language/prism-show-language.js +++ b/plugins/show-language/prism-show-language.js @@ -151,6 +151,8 @@ "kt": "Kotlin", "kumir": "KuMir (КуМир)", "kum": "KuMir (КуМир)", + "ltl": "Lateralus", + "lat": "Lateralus", "latex": "LaTeX", "tex": "TeX", "context": "ConTeXt", diff --git a/tests/languages/lateralus/attribute_feature.test b/tests/languages/lateralus/attribute_feature.test new file mode 100644 index 0000000000..34eccb5615 --- /dev/null +++ b/tests/languages/lateralus/attribute_feature.test @@ -0,0 +1,35 @@ +#[caps(io, net)] +@inline +@deprecated +#!["crate-level"] + +---------------------------------------------------- + +[ + ["attribute", [ + ["punctuation", "#["], + "caps(io, net)", + ["punctuation", "]"] + ]], + + ["attribute", [ + ["punctuation", "@"], + "inline" + ]], + + ["attribute", [ + ["punctuation", "@"], + "deprecated" + ]], + + "\r\n#", + ["operator", "!"], + ["punctuation", "["], + ["string", ["\"crate-level\""]], + ["punctuation", "]"] +] + + +---------------------------------------------------- + +Checks for attribute decorators, capability annotations, and crate-level attributes. diff --git a/tests/languages/lateralus/builtin-type_feature.test b/tests/languages/lateralus/builtin-type_feature.test new file mode 100644 index 0000000000..7ff14a1b29 --- /dev/null +++ b/tests/languages/lateralus/builtin-type_feature.test @@ -0,0 +1,56 @@ +i8 +i16 +i32 +i64 +i128 +isize +u8 +u16 +u32 +u64 +u128 +usize +f32 +f64 +bool +char +str +string +void +Result +Option +Vec +HashMap + +---------------------------------------------------- + +[ + ["builtin-type", "i8"], + ["builtin-type", "i16"], + ["builtin-type", "i32"], + ["builtin-type", "i64"], + ["builtin-type", "i128"], + ["builtin-type", "isize"], + ["builtin-type", "u8"], + ["builtin-type", "u16"], + ["builtin-type", "u32"], + ["builtin-type", "u64"], + ["builtin-type", "u128"], + ["builtin-type", "usize"], + ["builtin-type", "f32"], + ["builtin-type", "f64"], + ["builtin-type", "bool"], + ["builtin-type", "char"], + ["builtin-type", "str"], + ["builtin-type", "string"], + ["builtin-type", "void"], + ["builtin-type", "Result"], + ["builtin-type", "Option"], + ["builtin-type", "Vec"], + ["builtin-type", "HashMap"] +] + + +---------------------------------------------------- + +Checks for built-in types. diff --git a/tests/languages/lateralus/comment_feature.test b/tests/languages/lateralus/comment_feature.test new file mode 100644 index 0000000000..9f2805f5de --- /dev/null +++ b/tests/languages/lateralus/comment_feature.test @@ -0,0 +1,18 @@ +// single line comment +/// doc comment +/* block comment */ +/* outer /* inner */ still outer */ + +---------------------------------------------------- + +[ + ["comment", "// single line comment"], + ["comment", "/// doc comment"], + ["comment", "/* block comment */"], + ["comment", "/* outer /* inner */ still outer */"] +] + + +---------------------------------------------------- + +Checks for line, doc, and nested block comments. diff --git a/tests/languages/lateralus/keyword_feature.test b/tests/languages/lateralus/keyword_feature.test new file mode 100644 index 0000000000..1365cc3e93 --- /dev/null +++ b/tests/languages/lateralus/keyword_feature.test @@ -0,0 +1,76 @@ +fn +let +const +var +mut +if +else +match +for +while +loop +return +break +continue +struct +enum +trait +impl +type +pub +use +import +module +self +async +await +actor +spawn +true +false +nil +None +Some + +---------------------------------------------------- + +[ + ["keyword", "fn"], + ["keyword", "let"], + ["keyword", "const"], + ["keyword", "var"], + ["keyword", "mut"], + ["keyword", "if"], + ["keyword", "else"], + ["keyword", "match"], + ["keyword", "for"], + ["keyword", "while"], + ["keyword", "loop"], + ["keyword", "return"], + ["keyword", "break"], + ["keyword", "continue"], + ["keyword", "struct"], + ["keyword", "enum"], + ["keyword", "trait"], + ["keyword", "impl"], + ["keyword", "type"], + ["keyword", "pub"], + ["keyword", "use"], + ["keyword", "import"], + ["keyword", "module"], + ["keyword", "self"], + ["keyword", "async"], + ["keyword", "await"], + ["keyword", "actor"], + ["keyword", "spawn"], + ["constant", "true"], + ["constant", "false"], + ["constant", "nil"], + ["constant", "None"], + ["constant", "Some"] +] + + +---------------------------------------------------- + +Checks for keywords and constants. diff --git a/tests/languages/lateralus/number_feature.test b/tests/languages/lateralus/number_feature.test new file mode 100644 index 0000000000..30e2ddca66 --- /dev/null +++ b/tests/languages/lateralus/number_feature.test @@ -0,0 +1,32 @@ +42 +1_000_000 +0xFF +0xDEAD_BEEF +0b1010_1100 +0o755 +3.14 +3.14_f32 +42u64 +0xFF_i32 +1_000.5e-10 + +---------------------------------------------------- + +[ + ["number", "42"], + ["number", "1_000_000"], + ["number", "0xFF"], + ["number", "0xDEAD_BEEF"], + ["number", "0b1010_1100"], + ["number", "0o755"], + ["number", "3.14"], + ["number", "3.14_f32"], + ["number", "42u64"], + ["number", "0xFF_i32"], + ["number", "1_000.5e-10"] +] + + +---------------------------------------------------- + +Checks for numeric literals with separators and type suffixes. diff --git a/tests/languages/lateralus/operator_feature.test b/tests/languages/lateralus/operator_feature.test new file mode 100644 index 0000000000..f61108ae69 --- /dev/null +++ b/tests/languages/lateralus/operator_feature.test @@ -0,0 +1,54 @@ +|> +-> +=> +:: +.. +..= +== +!= +<= +>= +&& +|| +<< +>> ++ +- +* +/ +% += ++= +-= + +---------------------------------------------------- + +[ + ["operator", "|>"], + ["operator", "->"], + ["operator", "=>"], + ["operator", "::"], + ["operator", ".."], + ["operator", "..="], + ["operator", "=="], + ["operator", "!="], + ["operator", "<="], + ["operator", ">="], + ["operator", "&&"], + ["operator", "||"], + ["operator", "<<"], + ["operator", ">>"], + ["operator", "+"], + ["operator", "-"], + ["operator", "*"], + ["operator", "/"], + ["operator", "%"], + ["operator", "="], + ["operator", "+="], + ["operator", "-="] +] + + +---------------------------------------------------- + +Checks for operators including pipeline and path separators. diff --git a/tests/languages/lateralus/string_feature.test b/tests/languages/lateralus/string_feature.test new file mode 100644 index 0000000000..3f0e5887bd --- /dev/null +++ b/tests/languages/lateralus/string_feature.test @@ -0,0 +1,36 @@ +"hello" +"with \"escape\"" +"interpolation {name}" +r"raw \n not escaped" +r#"with "quotes""# +b"bytes" +'a' +'\n' +'\u{1F600}' + +---------------------------------------------------- + +[ + ["string", ["\"hello\""]], + ["string", ["\"with \\\"escape\\\"\""]], + ["string", [ + "\"interpolation ", + ["interpolation", [ + ["interpolation-punctuation", "{"], + "name", + ["interpolation-punctuation", "}"] + ]], + "\"" + ]], + ["string", "r\"raw \\n not escaped\""], + ["string", "r#\"with \"quotes\"\"#"], + ["string", "b\"bytes\""], + ["char", "'a'"], + ["char", "'\\n'"], + ["char", "'\\u{1F600}'"] +] + + +---------------------------------------------------- + +Checks for string variants, interpolation, raw strings, byte strings, and char literals.