1% This file defines a NASM editor mode for the JED editor.
2% JED's home page is http://space.mit.edu/~davis/jed.html.
3%
4% To install, copy this file into your JED_LIBRARY directory
5% (/usr/local/jed/lib or C:\JED\LIB or whatever), then add the
6% following lines to your .jedrc or jed.rc file:
7%   autoload("nasm_mode", "nasm");
8%   add_mode_for_extension("nasm", "asm");
9% (you can of course replace "asm" with whatever file extension
10% you like to use for your NASM source files).
11
12variable Nasm_Instruction_Indent = 10;
13variable Nasm_Comment_Column = 33;
14variable Nasm_Comment_Space = 1;
15
16variable nasm_kw_2 = strcat("ahalaxbhblbpbtbxchclcscxdbdddhdidldqdsdtdwdxes",
17			    "fsgsinjajbjcjejgjljojpjsjzorsispssto");
18variable nasm_kw_3 = strncat("a16a32aaaaadaamaasadcaddandbsfbsrbtcbtrbtscbw",
19			     "cdqclccldclicmccmpcr0cr2cr3cr4cwddaadasdecdiv",
20			     "dr0dr1dr2dr3dr6dr7eaxebpebxecxediedxequesiesp",
21			     "farfldfsthltincintjaejbejgejlejmpjnajnbjncjne",
22			     "jngjnljnojnpjnsjnzjpejpolarldslealeslfslgslsl",
23			     "lssltrmm0mm1mm2mm3mm4mm5mm6mm7movmulnegnopnot",
24			     "o16o32outpopporrclrcrrepretrolrorrsmsalsarsbb",
25			     "segshlshrsmist0st1st2st3st4st5st6st7stcstdsti",
26			     "strsubtr3tr4tr5tr6tr7wrtxor", 9);
27variable nasm_kw_4 = strncat("arplbytecallcltscwdeemmsfabsfaddfbldfchsfcom",
28			     "fcosfdivfenifildfistfld1fldzfmulfnopfsinfstp",
29			     "fsubftstfxamfxchibtsidivimulinsbinsdinswint1",
30			     "int3intoinvdiretjcxzjnaejnbejngejnlelahflgdt",
31			     "lidtlldtlmswlocklongloopmovdmovqnearpandpopa",
32			     "popfpushpxorreperepzresbresdresqrestreswretf",
33			     "retnsahfsalcsetasetbsetcsetesetgsetlsetosetp",
34			     "setssetzsgdtshldshrdsidtsldtsmswtestumovverr",
35			     "verwwaitwordxaddxbtsxchg", 9);
36variable nasm_kw_5 = strncat("boundbswapcmovacmovbcmovccmovecmovgcmovlcmovo",
37			     "cmovpcmovscmovzcmpsbcmpsdcmpswcpuiddwordenter",
38			     "f2xm1faddpfbstpfclexfcomifcompfdisifdivpfdivr",
39			     "ffreefiaddficomfidivfimulfinitfistpfisubfldcw",
40			     "fldpifmulpfpremfptanfsavefsqrtfstcwfstswfsubp",
41			     "fsubrfucomfyl2xicebpint01iretdiretwjecxzleave",
42			     "lodsblodsdlodswloopeloopzmovsbmovsdmovswmovsx",
43			     "movzxoutsboutsdoutswpaddbpadddpaddwpandnpopad",
44			     "popawpopfdpopfwpslldpsllqpsllwpsradpsrawpsrld",
45			     "psrlqpsrlwpsubbpsubdpsubwpushapushfqwordrdmsr",
46			     "rdpmcrdtscrepnerepnzscasbscasdscaswsetaesetbe",
47			     "setgesetlesetnasetnbsetncsetnesetngsetnlsetno",
48			     "setnpsetnssetnzsetpesetposhortstosbstosdstosw",
49			     "timestwordwrmsrxlatb", 14);
50variable nasm_kw_6 = strncat("cmovaecmovbecmovgecmovlecmovnacmovnbcmovnc",
51			     "cmovnecmovngcmovnlcmovnocmovnpcmovnscmovnz",
52			     "cmovpecmovpofcmovbfcmovefcmovufcomipfcompp",
53			     "fdivrpficompfidivrfisubrfldenvfldl2efldl2t",
54			     "fldlg2fldln2fpatanfprem1frstorfscalefsetpm",
55			     "fstenvfsubrpfucomifucompincbininvlpgloopne",
56			     "loopnzpaddsbpaddswpmulhwpmullwpsubsbpsubsw",
57			     "pushadpushawpushfdpushfwsetnaesetnbesetnge",
58			     "setnlewbinvd", 9);
59variable nasm_kw_7 = strncat("cmovnaecmovnbecmovngecmovnlecmpxchgfcmovbe",
60			     "fcmovnbfcmovnefcmovnufdecstpfincstpfrndint",
61			     "fsincosfucomipfucomppfxtractfyl2xp1loadall",
62			     "paddusbpadduswpcmpeqbpcmpeqdpcmpeqwpcmpgtb",
63			     "pcmpgtdpcmpgtwpmaddwdpsubusbpsubusw", 5);
64variable nasm_kw_8 = "fcmovnbepackssdwpacksswbpackuswb";
65variable nasm_kw_9 = strcat("cmpxchg8bpunpckhbwpunpckhdqpunpckhwdpunpcklbw",
66			    "punpckldqpunpcklwd");
67variable nasm_kw_10 = "cmpxchg486loadall286";
68
69define nasm_indent_line() {
70    variable word, len, e, c;
71
72    e = eolp();
73
74    push_spot();
75    EXIT_BLOCK {
76	pop_spot();
77	if (what_column() <= Nasm_Instruction_Indent)
78	    skip_white();
79    }
80
81    bol_skip_white();
82    c = what_column();
83
84    if (orelse
85       {looking_at_char(';')}
86       {looking_at_char('#')}
87       {looking_at_char('[')}) {
88	bol_trim();
89	pop_spot();
90	EXIT_BLOCK {
91	}
92	return;
93    }
94
95    if (looking_at_char('%')) {
96	go_right_1();
97	!if (orelse
98	    {looking_at_char('$')}
99	    {looking_at_char('%')}
100	    {looking_at_char('+')}
101	    {looking_at_char('-')}
102	    {looking_at_char('0')}
103	    {looking_at_char('1')}
104	    {looking_at_char('2')}
105	    {looking_at_char('3')}
106	    {looking_at_char('4')}
107	    {looking_at_char('5')}
108	    {looking_at_char('6')}
109	    {looking_at_char('7')}
110	    {looking_at_char('8')}
111	    {looking_at_char('9')}) {
112	    bol_trim();
113	    pop_spot();
114	    EXIT_BLOCK {
115	    }
116	    return;
117	}
118	go_left_1();
119    }
120
121    push_mark();
122    skip_chars("%$+-");
123    skip_chars("0-9a-zA-Z_.");
124    word = bufsubstr();
125
126    if (orelse
127       {c == 1}
128       {looking_at_char(':')}) {
129	push_spot();
130	bol_trim();
131	pop_spot();
132	len = strlen(word);
133	if (looking_at_char(':')) {
134	    go_right_1();
135	    len++;
136	}
137	trim();
138	if (e or not(eolp())) {
139	    if (len >= Nasm_Instruction_Indent) {
140		pop();
141		whitespace(1);
142	    } else
143		whitespace(Nasm_Instruction_Indent - len);
144	    if (e) {
145		pop_spot();
146		eol();
147		push_spot();
148	    }
149	}
150    } else {
151	bol_trim();
152	whitespace(Nasm_Instruction_Indent);
153    }
154}
155
156define nasm_newline_indent() {
157    push_spot();
158    bol_skip_white();
159    if (eolp())
160	trim();
161    pop_spot();
162    newline();
163    nasm_indent_line();
164}
165
166define nasm_bol_self_ins() {
167    push_spot();
168    bskip_white();
169    bolp();
170    pop_spot();
171
172    call("self_insert_cmd");
173
174    % Grotty: force immediate update of the syntax highlighting.
175    insert_char('.');
176    deln(left(1));
177
178    if (())
179	nasm_indent_line();
180}
181
182define nasm_self_ins_ind() {
183    call("self_insert_cmd");
184
185    % Grotty: force immediate update of the syntax highlighting.
186    insert_char('.');
187    deln(left(1));
188
189    nasm_indent_line();
190}
191
192define nasm_insert_comment() {
193    variable spc;
194
195    bol_skip_white();
196    if (looking_at_char(';')) {
197	bol_trim();
198	go_right(1);
199	skip_white();
200	return;
201    } else if (eolp()) {
202	bol_trim();
203	insert("; ");
204	return;
205    }
206
207    forever {
208	skip_chars("^;\n'\"");
209	if (looking_at_char('\'')) {
210	    go_right_1();
211	    skip_chars("^'\n");
212	    !if (eolp())
213		go_right_1();
214	} else if (looking_at_char('\"')) {
215	    go_right_1();
216	    skip_chars("^\"\n");
217	    !if (eolp())
218		go_right_1();
219	} else if (looking_at_char(';')) {
220	    !if (bolp()) {
221		go_left_1();
222		trim();
223		!if (looking_at_char(';'))
224		    go_right_1();
225	    }
226	    break;
227	} else {
228	    break;
229	}
230    }
231    spc = Nasm_Comment_Column - what_column();
232    if (spc < Nasm_Comment_Space)
233	spc = Nasm_Comment_Space;
234    whitespace(spc);
235    if (eolp()) {
236	insert("; ");
237    } else {
238	go_right_1();
239	skip_white();
240    }
241}
242
243$1 = "NASM";
244create_syntax_table($1);
245
246define_syntax (";", "", '%', $1);
247define_syntax ("([", ")]", '(', $1);
248define_syntax ('"', '"', $1);
249define_syntax ('\'', '\'', $1);
250define_syntax ("0-9a-zA-Z_.@#", 'w', $1);
251define_syntax ("-+0-9a-fA-F.xXL", '0', $1);
252define_syntax (",:", ',', $1);
253define_syntax ('%', '#', $1);
254define_syntax ("|^&<>+-*/%~", '+', $1);
255
256set_syntax_flags($1,1);
257
258#ifdef HAS_DFA_SYNTAX
259
260dfa_enable_highlight_cache("nasm.dfa", $1);
261dfa_define_highlight_rule(";.*$", "comment", $1);
262dfa_define_highlight_rule("[A-Za-z_\\.\\?][A-Za-z0-9_\\.\\?\\$#@~]*",
263		      "Knormal", $1);
264dfa_define_highlight_rule("$([A-Za-z_\\.\\?][A-Za-z0-9_\\.\\?\\$#@~]*)?",
265		      "normal", $1);
266dfa_define_highlight_rule("[0-9]+(\\.[0-9]*)?([Ee][\\+\\-]?[0-9]*)?",
267		      "number", $1);
268dfa_define_highlight_rule("[0-9]+[QqBb]", "number", $1);
269dfa_define_highlight_rule("(0x|\\$[0-9A-Fa-f])[0-9A-Fa-f]*", "number", $1);
270dfa_define_highlight_rule("[0-9A-Fa-f]+[Hh]", "number", $1);
271dfa_define_highlight_rule("\"[^\"]*\"", "string", $1);
272dfa_define_highlight_rule("\"[^\"]*$", "string", $1);
273dfa_define_highlight_rule("'[^']*'", "string", $1);
274dfa_define_highlight_rule("'[^']*$", "string", $1);
275dfa_define_highlight_rule("[\\(\\)\\[\\],:]*", "delimiter", $1);
276dfa_define_highlight_rule("^[ \t]*#", "PQpreprocess", $1);
277dfa_define_highlight_rule("^[ \t]*\\%{?[^%\\$\\+\\-0-9]", "PQpreprocess", $1);
278dfa_define_highlight_rule("^%$", "preprocess", $1);
279dfa_define_highlight_rule("[\\|\\^&<>\\+\\-\\*/%~]*", "operator", $1);
280dfa_define_highlight_rule("%([%\\$]?-?[0-9A-Za-z_\\.\\?\\$~@]+|{[^}]*}?)",
281		      "preprocess", $1);
282dfa_define_highlight_rule("[ \t]*", "normal", $1);
283dfa_define_highlight_rule(".", "normal", $1);
284dfa_build_highlight_table($1);
285#endif
286
287define_keywords_n($1, nasm_kw_2, 2, 0);
288define_keywords_n($1, nasm_kw_3, 3, 0);
289define_keywords_n($1, nasm_kw_4, 4, 0);
290define_keywords_n($1, nasm_kw_5, 5, 0);
291define_keywords_n($1, nasm_kw_6, 6, 0);
292define_keywords_n($1, nasm_kw_7, 7, 0);
293define_keywords_n($1, nasm_kw_8, 8, 0);
294define_keywords_n($1, nasm_kw_9, 9, 0);
295define_keywords_n($1, nasm_kw_10, 10, 0);
296
297define_keywords_n($1, "org", 3, 1);
298define_keywords_n($1, "bitsiend", 4, 1);
299define_keywords_n($1, "aligngroupstruc", 5, 1);
300define_keywords_n($1, "alignbcommonexternglobalistruc", 6, 1);
301define_keywords_n($1, "sectionsegmentlibrary", 7, 1);
302define_keywords_n($1, "absoluteendstruc", 8, 1);
303define_keywords_n($1, "uppercase", 9, 1);
304
305!if (keymap_p ($1)) make_keymap ($1);
306definekey("nasm_bol_self_ins", ";", $1);
307definekey("nasm_bol_self_ins", "#", $1);
308definekey("nasm_bol_self_ins", "%", $1);
309definekey("nasm_bol_self_ins", "[", $1);
310definekey("nasm_self_ins_ind", ":", $1);
311definekey("nasm_insert_comment", "^[;", $1);
312
313define nasm_mode() {
314    set_mode("NASM", 4);
315    use_keymap ("NASM");
316    use_syntax_table ("NASM");
317    set_buffer_hook ("indent_hook", "nasm_indent_line");
318    set_buffer_hook ("newline_indent_hook", "nasm_newline_indent");
319    runhooks("nasm_mode_hook");
320}
321