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 @@ +
// single-line
+/// doc comment
+/* block
+ /* nested */
+ still a comment */
+
+let s = "hello, {name}!"
+let raw = r"C:\path\to\file"
+let multi = r#"quotes "inside" are fine"#
+let bytes = b"\x00\xFF"
+
+let a: u64 = 42_u64
+let b = 0xFF_i32
+let c = 0b1010_1100
+let d = 3.14_f32
+let e = 1_000_000
+
+#[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()
+}
+
+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,
+ }
+ }
+}
+
+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.