Skip to content

Commit cb75d9e

Browse files
Added support for SML (#2537)
1 parent 3b4f14c commit cb75d9e

18 files changed

+544
-3
lines changed

components.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components.json

+8
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,14 @@
10531053
"require": "markup-templating",
10541054
"owner": "Golmote"
10551055
},
1056+
"sml": {
1057+
"title": "SML",
1058+
"alias": "smlnj",
1059+
"aliasTitles": {
1060+
"smlnj": "SML/NJ"
1061+
},
1062+
"owner": "RunDevelopment"
1063+
},
10561064
"solidity": {
10571065
"title": "Solidity (Ethereum)",
10581066
"alias": "sol",

components/prism-sml.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// https://smlfamily.github.io/sml97-defn.pdf
2+
// https://people.mpi-sws.org/~rossberg/sml.html
3+
(function (Prism) {
4+
5+
var keywords = /\b(?:abstype|and|andalso|as|case|datatype|do|else|end|eqtype|exception|fn|fun|functor|handle|if|in|include|infix|infixr|let|local|nonfix|of|op|open|orelse|raise|rec|sharing|sig|signature|struct|structure|then|type|val|where|while|with|withtype)\b/i;
6+
7+
Prism.languages.sml = {
8+
// allow one level of nesting
9+
'comment': /\(\*(?:[^*(]|\*(?!\))|\((?!\*)|\(\*(?:[^*(]|\*(?!\))|\((?!\*))*\*\))*\*\)/,
10+
'string': {
11+
pattern: /#?"(?:[^"\\]|\\.)*"/,
12+
greedy: true
13+
},
14+
15+
'class-name': [
16+
{
17+
// This is only an approximation since the real grammar is context-free
18+
//
19+
// Why the main loop so complex?
20+
// The main loop is approximately the same as /(?:\s*(?:[*,]|->)\s*<TERMINAL>)*/ which is, obviously, a lot
21+
// simpler. The difference is that if a comma is the last iteration of the loop, then the terminal must be
22+
// followed by a long identifier.
23+
pattern: RegExp(
24+
/((?:^|[^:]):\s*)<TERMINAL>(?:\s*(?:(?:\*|->)\s*<TERMINAL>|,\s*<TERMINAL>(?:(?=<NOT-LAST>)|(?!<NOT-LAST>)\s+<LONG-ID>)))*/.source
25+
.replace(/<NOT-LAST>/g, function () { return /\s*(?:[*,]|->)/.source; })
26+
.replace(/<TERMINAL>/g, function () {
27+
return /(?:'[\w']*|<LONG-ID>|\((?:[^()]|\([^()]*\))*\)|\{(?:[^{}]|\{[^{}]*\})*\})(?:\s+<LONG-ID>)*/.source;
28+
})
29+
.replace(/<LONG-ID>/g, function () { return /(?!<KEYWORD>)[a-z\d_][\w'.]*/.source; })
30+
.replace(/<KEYWORD>/g, function () { return keywords.source; }),
31+
'i'
32+
),
33+
lookbehind: true,
34+
greedy: true,
35+
inside: null // see below
36+
},
37+
{
38+
pattern: /((?:^|[^\w'])(?:datatype|exception|functor|signature|structure|type)\s+)[a-z_][\w'.]*/i,
39+
lookbehind: true
40+
}
41+
],
42+
'function': {
43+
pattern: /((?:^|[^\w'])fun\s+)[a-z_][\w'.]*/i,
44+
lookbehind: true
45+
},
46+
47+
'keyword': keywords,
48+
'variable': {
49+
pattern: /(^|[^\w'])'[\w']*/,
50+
lookbehind: true,
51+
},
52+
53+
'number': /~?\b(?:\d+(?:\.\d+)?(?:e~?\d+)?|0x[\da-f]+)\b/i,
54+
'word': {
55+
pattern: /\b0w(?:\d+|x[\da-f]+)\b/i,
56+
alias: 'constant'
57+
},
58+
59+
'boolean': /\b(?:false|true)\b/i,
60+
'operator': /\.\.\.|:[>=:]|=>?|->|[<>]=?|[!+\-*/^#|@~]/,
61+
'punctuation': /[(){}\[\].:,;]/
62+
};
63+
64+
Prism.languages.sml['class-name'][0].inside = Prism.languages.sml;
65+
66+
Prism.languages.smlnj = Prism.languages.sml;
67+
68+
}(Prism));

components/prism-sml.min.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/prism-sml.html

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<h2>Full example</h2>
2+
<pre><code>(* source: https://github.com/HarrisonGrodin/ml-numbers/blob/ba35c763092052e391871edf224f17474c6231b1/src/Rational.sml *)
3+
4+
structure Rational :> RATIONAL =
5+
struct
6+
type t = int * int (* (a,b) invariant: a,b coprime; b nonnegative *)
7+
8+
local
9+
val rec gcd = fn
10+
(m,0) => m
11+
| (m,n) => gcd (n, m mod n)
12+
in
13+
infix 8 //
14+
val op // = fn (x,y) => (
15+
let
16+
val gcd = gcd (x,y)
17+
in
18+
(x div gcd, y div gcd)
19+
end
20+
)
21+
end
22+
23+
val show = Fn.id
24+
25+
val zero = (0,1)
26+
val one = (1,1)
27+
28+
val eq : t * t -> bool = (op =)
29+
val compare = fn ((a,b),(x,y)) => Int.compare (a * y, b * x)
30+
val toString = fn (x,y) => Int.toString x ^ " // " ^ Int.toString y
31+
val percent =
32+
Fn.curry (Fn.flip (op ^)) "%"
33+
o Int.toString
34+
o (fn (a,b) => (100 * a) div b)
35+
36+
val op + = fn ((a,b),(x,y)) => (a * y + b * x) // (b * y)
37+
val ~ = fn (a,b) => (~a,b)
38+
val op - = fn (r1,r2) => r1 + ~r2
39+
40+
val op * = fn ((a,b),(x,y)) => (a * x) // (b * y)
41+
val inv = Fn.flip (op //)
42+
val op / = fn (r1,r2) => r1 * inv r2
43+
end</code></pre>

plugins/autoloader/prism-autoloader.js

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
"rb": "ruby",
208208
"sh-session": "shell-session",
209209
"shellsession": "shell-session",
210+
"smlnj": "sml",
210211
"sol": "solidity",
211212
"sln": "solution-file",
212213
"rq": "sparql",

plugins/autoloader/prism-autoloader.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/show-language/prism-show-language.js

+2
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@
169169
"shell-session": "Shell session",
170170
"sh-session": "Shell session",
171171
"shellsession": "Shell session",
172+
"sml": "SML",
173+
"smlnj": "SML/NJ",
172174
"solidity": "Solidity (Ethereum)",
173175
"sol": "Solidity (Ethereum)",
174176
"solution-file": "Solution file",

0 commit comments

Comments
 (0)