Skip to content

Commit f053af1

Browse files
Pascal: Added support for asm and directives (#2653)
Co-authored-by: RunDevelopment <mitchi5000.ms@googlemail.com>
1 parent d63d6c0 commit f053af1

File tree

4 files changed

+378
-6
lines changed

4 files changed

+378
-6
lines changed

components/prism-pascal.js

+21-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,25 @@
55
*/
66

77
Prism.languages.pascal = {
8-
'comment': [
9-
/\(\*[\s\S]+?\*\)/,
10-
/\{[\s\S]+?\}/,
11-
/\/\/.*/
12-
],
8+
'directive': {
9+
pattern: /\{\$[\s\S]*?\}/,
10+
greedy: true,
11+
alias: ['marco', 'property']
12+
},
13+
'comment': {
14+
pattern: /\(\*[\s\S]*?\*\)|\{[\s\S]*?\}|\/\/.*/,
15+
greedy: true
16+
},
1317
'string': {
1418
pattern: /(?:'(?:''|[^'\r\n])*'(?!')|#[&$%]?[a-f\d]+)+|\^[a-z]/i,
1519
greedy: true
1620
},
21+
'asm': {
22+
pattern: /(\basm\b)[\s\S]+?(?=\bend\s*[;[])/i,
23+
lookbehind: true,
24+
greedy: true,
25+
inside: null // see below
26+
},
1727
'keyword': [
1828
{
1929
// Turbo Pascal
@@ -52,4 +62,10 @@ Prism.languages.pascal = {
5262
'punctuation': /\(\.|\.\)|[()\[\]:;,.]/
5363
};
5464

65+
Prism.languages.pascal.asm.inside = Prism.languages.extend('pascal', {
66+
'asm': undefined,
67+
'keyword': undefined,
68+
'operator': undefined
69+
});
70+
5571
Prism.languages.objectpascal = Prism.languages.pascal;

components/prism-pascal.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+344
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
program asmDemo(input, output, stderr);
2+
3+
// The $asmMode directive informs the compiler
4+
// which syntax is used in asm-blocks.
5+
// Alternatives are 'att' (AT&T syntax) and 'direct'.
6+
{$asmMode intel}
7+
8+
var
9+
n, m: longint;
10+
begin
11+
n := 42;
12+
m := -7;
13+
writeLn('n = ', n, '; m = ', m);
14+
15+
// instead of declaring another temporary variable
16+
// and writing "tmp := n; n := m; m := tmp;":
17+
asm
18+
mov eax, n // eax := n
19+
// xchg can only operate at most on one memory address
20+
xchg eax, m // swaps values in eax and at m
21+
mov n, eax // n := eax (holding the former m value)
22+
// an array of strings after the asm-block closing 'end'
23+
// tells the compiler which registers have changed
24+
// (you don't wanna mess with the compiler's notion
25+
// which registers mean what)
26+
end ['eax'];
27+
28+
writeLn('n = ', n, '; m = ', m);
29+
end.
30+
31+
program sign(input, output, stderr);
32+
33+
type
34+
signumCodomain = -1..1;
35+
36+
{ returns the sign of an integer }
37+
function signum({$ifNDef CPUx86_64} const {$endIf} x: longint): signumCodomain;
38+
{$ifDef CPUx86_64} // ============= optimized implementation
39+
assembler;
40+
{$asmMode intel}
41+
asm
42+
xor rax, rax // ensure result is not wrong
43+
// due to any residue
44+
45+
test x, x // x ≟ 0
46+
setnz al // al ≔ ¬ZF
47+
48+
sar x, 63 // propagate sign-bit through reg.
49+
cmovs rax, x // if SF then rax ≔ −1
50+
end;
51+
{$else} // ========================== default implementation
52+
begin
53+
// This is what math.sign virtually does.
54+
// The compiled code requires _two_ cmp instructions, though.
55+
if x > 0 then
56+
begin
57+
signum := 1;
58+
end
59+
else if x < 0 then
60+
begin
61+
signum := -1;
62+
end
63+
else
64+
begin
65+
signum := 0;
66+
end;
67+
end;
68+
{$endIf}
69+
70+
// M A I N =================================================
71+
var
72+
x: longint;
73+
begin
74+
readLn(x);
75+
writeLn(signum(x));
76+
end.
77+
78+
----------------------------------------------------
79+
80+
[
81+
["keyword", "program"],
82+
" asmDemo",
83+
["punctuation", "("],
84+
"input",
85+
["punctuation", ","],
86+
" output",
87+
["punctuation", ","],
88+
" stderr",
89+
["punctuation", ")"],
90+
["punctuation", ";"],
91+
92+
["comment", "// The $asmMode directive informs the compiler"],
93+
["comment", "// which syntax is used in asm-blocks."],
94+
["comment", "// Alternatives are 'att' (AT&T syntax) and 'direct'."],
95+
["directive", "{$asmMode intel}"],
96+
97+
["keyword", "var"],
98+
99+
"\r\n\tn",
100+
["punctuation", ","],
101+
" m",
102+
["punctuation", ":"],
103+
" longint",
104+
["punctuation", ";"],
105+
106+
["keyword", "begin"],
107+
108+
"\r\n\tn ",
109+
["operator", ":="],
110+
["number", "42"],
111+
["punctuation", ";"],
112+
113+
"\r\n\tm ",
114+
["operator", ":="],
115+
["operator", "-"],
116+
["number", "7"],
117+
["punctuation", ";"],
118+
119+
"\r\n\twriteLn",
120+
["punctuation", "("],
121+
["string", "'n = '"],
122+
["punctuation", ","],
123+
" n",
124+
["punctuation", ","],
125+
["string", "'; m = '"],
126+
["punctuation", ","],
127+
" m",
128+
["punctuation", ")"],
129+
["punctuation", ";"],
130+
131+
["comment", "// instead of declaring another temporary variable"],
132+
133+
["comment", "// and writing \"tmp := n; n := m; m := tmp;\":"],
134+
135+
["keyword", "asm"],
136+
["asm", [
137+
"\r\n\t\tmov eax",
138+
["punctuation", ","],
139+
" n ",
140+
["comment", "// eax := n"],
141+
142+
["comment", "// xchg can only operate at most on one memory address"],
143+
144+
"\r\n\t\txchg eax",
145+
["punctuation", ","],
146+
" m ",
147+
["comment", "// swaps values in eax and at m"],
148+
149+
"\r\n\t\tmov n",
150+
["punctuation", ","],
151+
" eax ",
152+
["comment", "// n := eax (holding the former m value)"],
153+
154+
["comment", "// an array of strings after the asm-block closing 'end'"],
155+
156+
["comment", "// tells the compiler which registers have changed"],
157+
158+
["comment", "// (you don't wanna mess with the compiler's notion"],
159+
160+
["comment", "// which registers mean what)"]
161+
]],
162+
["keyword", "end"],
163+
["punctuation", "["],
164+
["string", "'eax'"],
165+
["punctuation", "]"],
166+
["punctuation", ";"],
167+
168+
"\r\n\r\n\twriteLn",
169+
["punctuation", "("],
170+
["string", "'n = '"],
171+
["punctuation", ","],
172+
" n",
173+
["punctuation", ","],
174+
["string", "'; m = '"],
175+
["punctuation", ","],
176+
" m",
177+
["punctuation", ")"],
178+
["punctuation", ";"],
179+
180+
["keyword", "end"],
181+
["punctuation", "."],
182+
183+
["keyword", "program"],
184+
" sign",
185+
["punctuation", "("],
186+
"input",
187+
["punctuation", ","],
188+
" output",
189+
["punctuation", ","],
190+
" stderr",
191+
["punctuation", ")"],
192+
["punctuation", ";"],
193+
194+
["keyword", "type"],
195+
196+
"\r\n\tsignumCodomain ",
197+
["operator", "="],
198+
["operator", "-"],
199+
["number", "1"],
200+
["operator", ".."],
201+
["number", "1"],
202+
["punctuation", ";"],
203+
204+
["comment", "{ returns the sign of an integer }"],
205+
206+
["keyword", "function"],
207+
" signum",
208+
["punctuation", "("],
209+
["directive", "{$ifNDef CPUx86_64}"],
210+
["keyword", "const"],
211+
["directive", "{$endIf}"],
212+
" x",
213+
["punctuation", ":"],
214+
" longint",
215+
["punctuation", ")"],
216+
["punctuation", ":"],
217+
" signumCodomain",
218+
["punctuation", ";"],
219+
220+
["directive", "{$ifDef CPUx86_64}"],
221+
["comment", "// ============= optimized implementation"],
222+
223+
["keyword", "assembler"],
224+
["punctuation", ";"],
225+
226+
["directive", "{$asmMode intel}"],
227+
228+
["keyword", "asm"],
229+
["asm", [
230+
"\r\n\txor rax",
231+
["punctuation", ","],
232+
" rax ",
233+
["comment", "// ensure result is not wrong"],
234+
235+
["comment", "// due to any residue"],
236+
237+
"\r\n\r\n\ttest x",
238+
["punctuation", ","],
239+
" x ",
240+
["comment", "// x ≟ 0"],
241+
242+
"\r\n\tsetnz al ",
243+
["comment", "// al ≔ ¬ZF"],
244+
245+
"\r\n\r\n\tsar x",
246+
["punctuation", ","],
247+
["number", "63"],
248+
["comment", "// propagate sign-bit through reg."],
249+
250+
"\r\n\tcmovs rax",
251+
["punctuation", ","],
252+
" x ",
253+
["comment", "// if SF then rax ≔ −1"]
254+
]],
255+
["keyword", "end"],
256+
["punctuation", ";"],
257+
258+
["directive", "{$else}"],
259+
["comment", "// ========================== default implementation"],
260+
261+
["keyword", "begin"],
262+
263+
["comment", "// This is what math.sign virtually does."],
264+
265+
["comment", "// The compiled code requires _two_ cmp instructions, though."],
266+
267+
["keyword", "if"],
268+
" x ",
269+
["operator", ">"],
270+
["number", "0"],
271+
["keyword", "then"],
272+
273+
["keyword", "begin"],
274+
275+
"\r\n\t\tsignum ",
276+
["operator", ":="],
277+
["number", "1"],
278+
["punctuation", ";"],
279+
280+
["keyword", "end"],
281+
282+
["keyword", "else"],
283+
["keyword", "if"],
284+
" x ",
285+
["operator", "<"],
286+
["number", "0"],
287+
["keyword", "then"],
288+
289+
["keyword", "begin"],
290+
291+
"\r\n\t\tsignum ",
292+
["operator", ":="],
293+
["operator", "-"],
294+
["number", "1"],
295+
["punctuation", ";"],
296+
297+
["keyword", "end"],
298+
299+
["keyword", "else"],
300+
301+
["keyword", "begin"],
302+
303+
"\r\n\t\tsignum ",
304+
["operator", ":="],
305+
["number", "0"],
306+
["punctuation", ";"],
307+
308+
["keyword", "end"],
309+
["punctuation", ";"],
310+
311+
["keyword", "end"],
312+
["punctuation", ";"],
313+
314+
["directive", "{$endIf}"],
315+
316+
["comment", "// M A I N ================================================="],
317+
318+
["keyword", "var"],
319+
320+
"\r\n\tx",
321+
["punctuation", ":"],
322+
" longint",
323+
["punctuation", ";"],
324+
325+
["keyword", "begin"],
326+
327+
"\r\n\treadLn",
328+
["punctuation", "("],
329+
"x",
330+
["punctuation", ")"],
331+
["punctuation", ";"],
332+
333+
"\r\n\twriteLn",
334+
["punctuation", "("],
335+
"signum",
336+
["punctuation", "("],
337+
"x",
338+
["punctuation", ")"],
339+
["punctuation", ")"],
340+
["punctuation", ";"],
341+
342+
["keyword", "end"],
343+
["punctuation", "."]
344+
]

0 commit comments

Comments
 (0)