From ae8f8ef610fe87b5294b287fae9933f25d1d0996 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Tue, 29 Jul 2025 23:08:20 -0400 Subject: [PATCH 1/2] add IR syntaxes Co-authored-by: Claude --- .../api-initializers/theme-initializer.gjs | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/javascripts/discourse/api-initializers/theme-initializer.gjs b/javascripts/discourse/api-initializers/theme-initializer.gjs index 45f6474..d0a968f 100644 --- a/javascripts/discourse/api-initializers/theme-initializer.gjs +++ b/javascripts/discourse/api-initializers/theme-initializer.gjs @@ -627,6 +627,95 @@ function julia(hljs) { return DEFAULT; } +/* +Language: Julia IR +Description: Julia Static Single Assignment (SSA) form Intermediate Representation +Author: Matt Bauman (& Claude) +Website: https://docs.julialang.org/en/v1/devdocs/ssair/ +Category: scientific +Extends: julia.js +*/ + +function juliaIR(hljs) { + // Get the base Julia language definition + const julia = hljs.getLanguage('julia'); + + if (!julia) { + throw new Error('Julia language definition not found. Julia IR extends Julia.'); + } + + // Clone the Julia definition to avoid modifying the original + const juliaIR = { + ...julia, + name: 'julia-ir', + }; + + // Add IR-specific keywords to existing Julia keywords + const IR_KEYWORDS = [ + 'goto', 'not', 'invoke', 'call', 'enter', 'leave', + 'unreachable', 'φᶜ', 'φ', 'π', 'ϒ' + ]; + + // Extend keywords + if (juliaIR.keywords) { + juliaIR.keywords = { + ...juliaIR.keywords, + keyword: [...(juliaIR.keywords.keyword || []), ...IR_KEYWORDS] + }; + } + + // IR-specific patterns that need to be added to the contains array + const IR_PATTERNS = [ + // SSA values (%1, %2, etc.) - highest priority + { + scope: 'variable', + match: /%\d+/, + relevance: 10 + }, + + // Basic block labels (1 ─, 2 ┄, etc.) and box drawing + { + scope: 'section', + match: /^\s*\d*[ ─│╻╷└┃┌┄]+/, + relevance: 8 + }, + + // Control flow labels (#1, #2, etc.) + { + scope: 'symbol', + match: /#\d+/, + relevance: 5 + }, + + // Warned type annotations + { + scope: 'type.unstable', + match: /::(Any|Box)\b/, + relevance: 8 + }, + + // CodeInfo wrapper + { + scope: 'meta', + begin: /\bCodeInfo\s*\(/, + end: /$/, + contains: ['self'], + relevance: 10 + }, + ]; + + // Prepend IR patterns to the contains array (higher priority than base Julia patterns) + if (juliaIR.contains) { + juliaIR.contains = [...IR_PATTERNS, ...juliaIR.contains]; + } else { + juliaIR.contains = IR_PATTERNS; + } + + juliaIR.case_insensitive = false; + + return juliaIR; +} + /* Language: Julia REPL Description: Julia REPL sessions @@ -703,6 +792,30 @@ function juliaRepl(hljs) { ], }, }, + { + className: "meta.prompt", + begin: /^julia>(?=\s+@?code_(typed|lowered|warntype)\b)/, + relevance: 15, + starts: { + end: /^(?=julia>)/, + returnBegin: true, + contains: [ + { + // The Julia command line itself + begin: /\s+@?code_(typed|lowered|warntype)/, + end: /^(?![ ]{6})/, + subLanguage: "julia", + endsWithParent: true, + }, + { + // The IR that follows + begin: /^./, + subLanguage: "julia-ir", + endsWithParent: true, + }, + ], + }, + }, { className: "meta.prompt", begin: /^julia>/, @@ -777,6 +890,7 @@ function juliaRepl(hljs) { export default apiInitializer((api) => { api.registerHighlightJSLanguage("julia", julia); + api.registerHighlightJSLanguage("julia-ir", juliaIR); api.registerHighlightJSLanguage("julia-repl", juliaRepl); // Register meta-language that auto-detects between julia and julia-repl api.registerHighlightJSLanguage("julia-auto", function (hljs) { From 58535a0bcc2ce3815fd0c2f9c391ec2131105e9b Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Tue, 29 Jul 2025 23:11:03 -0400 Subject: [PATCH 2/2] style --- .../api-initializers/theme-initializer.gjs | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/javascripts/discourse/api-initializers/theme-initializer.gjs b/javascripts/discourse/api-initializers/theme-initializer.gjs index d0a968f..078f1e6 100644 --- a/javascripts/discourse/api-initializers/theme-initializer.gjs +++ b/javascripts/discourse/api-initializers/theme-initializer.gjs @@ -630,7 +630,7 @@ function julia(hljs) { /* Language: Julia IR Description: Julia Static Single Assignment (SSA) form Intermediate Representation -Author: Matt Bauman (& Claude) +Author: Matt Bauman Website: https://docs.julialang.org/en/v1/devdocs/ssair/ Category: scientific Extends: julia.js @@ -638,29 +638,40 @@ Extends: julia.js function juliaIR(hljs) { // Get the base Julia language definition - const julia = hljs.getLanguage('julia'); + const jl = hljs.getLanguage("julia"); - if (!julia) { - throw new Error('Julia language definition not found. Julia IR extends Julia.'); + if (!jl) { + throw new Error( + "Julia language definition not found. Julia IR extends Julia." + ); } // Clone the Julia definition to avoid modifying the original - const juliaIR = { - ...julia, - name: 'julia-ir', + const jlir = { + ...jl, + name: "julia-ir", }; // Add IR-specific keywords to existing Julia keywords const IR_KEYWORDS = [ - 'goto', 'not', 'invoke', 'call', 'enter', 'leave', - 'unreachable', 'φᶜ', 'φ', 'π', 'ϒ' + "goto", + "not", + "invoke", + "call", + "enter", + "leave", + "unreachable", + "φᶜ", + "φ", + "π", + "ϒ", ]; // Extend keywords - if (juliaIR.keywords) { - juliaIR.keywords = { - ...juliaIR.keywords, - keyword: [...(juliaIR.keywords.keyword || []), ...IR_KEYWORDS] + if (jlir.keywords) { + jlir.keywords = { + ...jlir.keywords, + keyword: [...(juliaIR.keywords.keyword || []), ...IR_KEYWORDS], }; } @@ -668,52 +679,52 @@ function juliaIR(hljs) { const IR_PATTERNS = [ // SSA values (%1, %2, etc.) - highest priority { - scope: 'variable', + scope: "variable", match: /%\d+/, - relevance: 10 + relevance: 10, }, // Basic block labels (1 ─, 2 ┄, etc.) and box drawing { - scope: 'section', + scope: "section", match: /^\s*\d*[ ─│╻╷└┃┌┄]+/, - relevance: 8 + relevance: 8, }, // Control flow labels (#1, #2, etc.) { - scope: 'symbol', + scope: "symbol", match: /#\d+/, - relevance: 5 + relevance: 5, }, // Warned type annotations { - scope: 'type.unstable', + scope: "type.unstable", match: /::(Any|Box)\b/, - relevance: 8 + relevance: 8, }, // CodeInfo wrapper { - scope: 'meta', + scope: "meta", begin: /\bCodeInfo\s*\(/, end: /$/, - contains: ['self'], - relevance: 10 + contains: ["self"], + relevance: 10, }, ]; // Prepend IR patterns to the contains array (higher priority than base Julia patterns) - if (juliaIR.contains) { - juliaIR.contains = [...IR_PATTERNS, ...juliaIR.contains]; + if (jlir.contains) { + jlir.contains = [...IR_PATTERNS, ...jlir.contains]; } else { - juliaIR.contains = IR_PATTERNS; + jlir.contains = IR_PATTERNS; } - juliaIR.case_insensitive = false; + jlir.case_insensitive = false; - return juliaIR; + return jlir; } /*