% -*- SLang -*- % avrmode.sl % A simple avr-asm mode, copied and % modified from the tiasm-mode (tiasm.sl) % % Jens Wilhelm Wulf 19.01.2006 % homepage: http://kisocd.sf.net/ % % Do as you wish with this code under the following conditions: % 1) leave this notice intact % 2) don't try to sell it % 3) don't try pretend it is your own code define avr_indentcomment() { bol(); if (ffind_char(';')) { fsearch(";"); if (what_column() < 30) insert_spaces(30-what_column()); } } define avr_autoindent() % ganze Zeile automatisch einrücken { variable zeile; variable level = 0; variable letzteZeile = 0; zeile = what_line(); bob(); % if_ und endif_ bis zu der Zeile zählen, die eingerückt werden soll while (what_line() <= zeile and letzteZeile == 0) { bol_skip_white(); if (looking_at(".if_") and what_line() < zeile) level++; else if (looking_at(".endif_")) level--; if (down_1() == 0) letzteZeile = 1; } if (letzteZeile == 0) go_up_1(); level = level * 2; bol_skip_white(); if (looking_at(".else_")) level -= 2; if ( looking_at("adc ") or looking_at("add ") or looking_at("and ") or looking_at("asr ") or looking_at("bld ") or looking_at("bst ") or looking_at("cbi ") or looking_at("cbr ") or looking_at("clr ") or looking_at("com ") or looking_at("cpc ") or looking_at("cpi ") or looking_at("dec ") or looking_at("eor ") or looking_at("inc ") or looking_at("jmp ") or looking_at("ldd ") or looking_at("ldi ") or looking_at("lds ") or looking_at("lsl ") or looking_at("lsr ") or looking_at("mov ") or looking_at("mul ") or looking_at("neg ") or looking_at("ori ") or looking_at("out ") or looking_at("pop ") or looking_at("rol ") or looking_at("ror ") or looking_at("sbc ") or looking_at("sbi ") or looking_at("sbr ") or looking_at("ser ") or looking_at("std ") or looking_at("sts ") or looking_at("sub ") or looking_at("tst ") or looking_at("adiw ") or looking_at("andi ") or looking_at("bclr ") or looking_at("brbc ") or looking_at("brbs ") or looking_at("brcc ") or looking_at("brcs ") or looking_at("breq ") or looking_at("brge ") or looking_at("brhc ") or looking_at("brhs ") or looking_at("brid ") or looking_at("brie ") or looking_at("brlo ") or looking_at("brlt ") or looking_at("brmi ") or looking_at("brne ") or looking_at("brpl ") or looking_at("brsh ") or looking_at("brtc ") or looking_at("brts ") or looking_at("brvc ") or looking_at("brvs ") or looking_at("bset ") or looking_at("call ") or looking_at("cpse ") or looking_at("fmul ") or looking_at("movw ") or looking_at("muls ") or looking_at("push ") or looking_at("rjmp ") or looking_at("sbci ") or looking_at("sbic ") or looking_at("sbis ") or looking_at("sbiw ") or looking_at("sbrc ") or looking_at("sbrs ") or looking_at("subi ") or looking_at("swap ") or looking_at("cp ") or looking_at("in ") or looking_at("ld ") or looking_at("or ") or looking_at("st ") or looking_at("fmuls ") or looking_at("mulsu ") or looking_at("rcall ") or looking_at("fmulsu ") ) { % Auf Spalte 4 rücken, es ist ein Befehl bol_trim(); insert_spaces(level+3); % Dieser Befehl sollte auch Parameter haben, % also auch die einrücken! skip_white(); skip_word_chars(); trim(); insert_spaces(level+13-what_column()); avr_indentcomment(); } else if (looking_at("nop ") or looking_at("reti ") or looking_at("ret ") or looking_at("ijmp ") or looking_at("eijmp ") or looking_at("icall ") or looking_at("eicall ") or looking_at("lpm ") or looking_at("elpm ") or looking_at("spm ") or looking_at("espm ") or looking_at("sec ") or looking_at("sen ") or looking_at("sez ") or looking_at("clc ") or looking_at("cln ") or looking_at("clz ") or looking_at("seh ") or looking_at("sei ") or looking_at("ses ") or looking_at("set ") or looking_at("sev ") or looking_at("cli ") or looking_at("clh ") or looking_at("cls ") or looking_at("clt ") or looking_at("clv ") or looking_at("sleep ") or looking_at("wdr ") or looking_at(".if_") or looking_at(".else_") or looking_at(".endif_") ) { % Auf Spalte 4 rücken, es ist ein Befehl ohne Parameter bol_trim(); insert_spaces(level+3); avr_indentcomment(); } else { % Vielleicht ist es ein Label? skip_chars("A-Za-z0-9_"); if (looking_at(":")) { bol_trim(); avr_indentcomment(); } else if (looking_at(";")) { % Es ist nur ein Kommentar. Wenn in der vorigen Zeile ein Kommentar % steht, der in der ersten Spalte beginnt, lässt man diesen auch % in der ersten Spalte beginnen. Ansonsten einrücken. bol_trim(); go_up_1(); bol(); if (looking_at(";")) { down_1(); } else { down_1(); insert_spaces(level+3); } } } } define avr_indent_line() { variable spalte; spalte = what_column(); avr_autoindent(); if (spalte < 4) goto_column( 4); else if (spalte < 13) goto_column(13); else if (spalte < 30) goto_column(30); else if (spalte < 40) goto_column(40); else if (spalte < 50) goto_column(50); else if (spalte < 60) goto_column(60); } define avr_newline() { variable spalte; spalte = what_column(); skip_white(); if (eolp()) { avr_autoindent(); % Zeile automatisch formatieren % die Zeile sollte in der selben Spalte beginnen wie die davor, % es sei denn, man hat ein Label eingegeben. bol(); skip_chars(" \t"); spalte = what_column(); eol(); newline(); if (spalte > 1) goto_column(spalte); else goto_column(4); } else { goto_column(spalte); newline(); } } static define avr_get_names (names, id) { push_spot(); bob(); % should be case insensitive variable oldcase = CASE_SEARCH; CASE_SEARCH = 0; while (bol_fsearch(id)) { go_right(6); skip_chars (" \t"); push_mark(); skip_chars ("a-zA-Z0-9_"); names [bufsubstr ()] = what_line(); } CASE_SEARCH = oldcase; pop_spot(); } static define avr_get_macro_names (names) { avr_get_names(names, ".macro"); } static define avr_get_proc_names (names) { avr_get_names(names, ".proc"); } static define avr_process_menu_popup (popup, func) { variable names = Assoc_Type[Int_Type]; push_spot_bob (); (@func) (names); pop_spot (); variable keys = assoc_get_keys (names); keys = keys[array_sort (keys)]; foreach (keys) { variable key = (); variable line = names[key]; menu_append_item (popup, key, &goto_line, line); } } static define avr_macro_popup_callback (popup) { avr_process_menu_popup (popup, &avr_get_macro_names); } static define avr_proc_popup_callback (popup) { avr_process_menu_popup (popup, &avr_get_proc_names); } public define avr_init_menu (menu) { menu_append_popup (menu, "&Proc"); menu_set_select_popup_callback (strcat (menu, ".&Proc"), &avr_proc_popup_callback); menu_append_popup (menu, "&Macro"); menu_set_select_popup_callback (strcat (menu, ".&Macro"), &avr_macro_popup_callback); } define avr_mode () { variable kmap = "avr"; % Was muss man bei set_mode() einstellen? Mit 0 und 4 ging TAB auf avr_indent_line % nicht, obwohl ich es weiter unten extra verbunden habe. set_mode(kmap, 2); mode_set_mode_info (kmap, "init_mode_menu", &avr_init_menu); use_syntax_table (kmap); set_buffer_hook ("indent_hook", "avr_indent_line"); unsetkey("^I"); setkey("avr_indent_line", "^I"); set_buffer_hook ("newline_indent_hook", "avr_newline"); mode_set_mode_info (kmap, "fold_info", ";{{{\r;}}}\r\r"); runhooks("avr_mode_hook"); } $1 = "avr"; create_syntax_table ($1); define_syntax (";", "", '%', $1); % Comment Syntax %define_syntax ('\\', '\\', $1); % Quote character %define_syntax ("{[", "}]", '(', $1); % are all these needed? %define_syntax ('\'', '"', $1); % string %define_syntax ("$~^_&#", '+', $1); % operators %define_syntax ("|&{}[],", ',', $1); % delimiters define_syntax ("a-zA-Z0-9.", 'w', $1); % "Words", normales Zeug halt define_syntax ('.', '#', $1); % compiler-Direktiven set_syntax_flags ($1, 1 | 2); set_fortran_comment_chars ($1, ";"); % Type 0 keywords () = define_keywords_n ($1, ".db.dwadcaddandasrbldbstcbicbrclcclhcliclnclrclscltclvclzcomcpccpideceorincjmplddldildslpmlsllsrmovmulnegnoporioutpopretrolrorsbcsbisbrsecsehseisensersessetsevsezspmstdstssubtstwdr", 3, 0); () = define_keywords_n ($1, ".def.equ.org.setadiwandibclrbrbcbrbsbrccbrcsbreqbrgebrhcbrhsbridbriebrlobrltbrmibrnebrplbrshbrtcbrtsbrvcbrvsbsetcallcpseelpmespmfmulijmpmovwmulspushretirjmpsbcisbicsbissbiwsbrcsbrssubiswap", 4, 0); () = define_keywords_n ($1, "cpinldorst", 2, 0); () = define_keywords_n ($1, ".byte.cseg.dseg.eseg.exit.listeijmpfmulsicallmulsurcallsleep", 5, 0); () = define_keywords_n ($1, ".macroeicallfmulsu", 6, 0); () = define_keywords_n ($1, ".device.nolist", 7, 0); () = define_keywords_n ($1, ".endmacro", 9, 0); () = define_keywords_n ($1, ".include.listmac", 8, 0); provide ("avrmode");