Module: LangScan::EmacsLisp
- Defined in:
- lib/langscan/elisp.rb,
ext/langscan/elisp/elisp/elisp.c
Defined Under Namespace
Classes: Tokenizer
Constant Summary collapse
- Keywords =
%w( defun defvar defmacro defgroup defcustom defconst and or condition-case function interactive require quote backquote lambda prog1 prog2 progn let let* if when unless cond catch throw save-current-buffer save-excursion save-restriction save-window-excurtion setq setq-default track-mouse unwind-protect while with-output-to-temp-buffer t nil )
- KeywordsHash =
{}
- NotFuncallWordsHash =
{"lambda" => "lambda"}
- NotFuncall2ndOuterWordsHash =
{"let" => "let", "let*" => "let*"}
Class Method Summary collapse
- .abbrev ⇒ Object
- .extnames ⇒ Object
- .funcall_list?(list) ⇒ Boolean
- .name ⇒ Object
- .quote_list?(list) ⇒ Boolean
- .quote_nestlevel(str) ⇒ Object
-
.scan(input, &block) ⇒ Object
LangScan::EmacsLisp.scan iterates over Emacs Lisp program.
- .scan_unsorted(input, &block) ⇒ Object
Class Method Details
.abbrev ⇒ Object
24 25 26 |
# File 'lib/langscan/elisp.rb', line 24 def abbrev "elisp" end |
.extnames ⇒ Object
28 29 30 |
# File 'lib/langscan/elisp.rb', line 28 def extnames [".el"] end |
.funcall_list?(list) ⇒ Boolean
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/langscan/elisp.rb', line 63 def funcall_list?(list) if list.before_open_length == 0 return true end if list.before_open_length >= 2 && list.around_open(-2).text == "defun" return false end if NotFuncallWordsHash[list.around_open(-1).text] return false end if quote_list?(list) return false end outer = list.outer second_outer = outer.outer unless outer == nil if second_outer and NotFuncall2ndOuterWordsHash[second_outer.around_open(1).text] if NotFuncall2ndOuterWordsHash[outer.around_open(-1).text] return false end end return true end |
.name ⇒ Object
20 21 22 |
# File 'lib/langscan/elisp.rb', line 20 def name "Emacs Lisp" end |
.quote_list?(list) ⇒ Boolean
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/langscan/elisp.rb', line 90 def quote_list?(list) l = list nest = 0 while l if l.before_open_length >= 1 before = l.around_open(-1) if before.type == :quote_chars return true if before.text.include?("'") nest = nest + quote_nestlevel(before.text) end end if l.after_open_length >= 1 after = l.around_open(1) if after.text == 'quote' return true elsif after.text == 'backquote' nest = nest + 1 elsif after.text == 'unquote' nest = nest - 1 end end l = l.outer end return nest > 0 end |
.quote_nestlevel(str) ⇒ Object
86 87 88 |
# File 'lib/langscan/elisp.rb', line 86 def quote_nestlevel(str) str.count("`") - str.count(",") end |
.scan(input, &block) ⇒ Object
LangScan::EmacsLisp.scan iterates over Emacs Lisp program. It yields for each Fragment.
34 35 36 37 |
# File 'lib/langscan/elisp.rb', line 34 def scan(input, &block) sorter = PairMatcher.fragmentsorter(block) scan_unsorted(input, &sorter) end |
.scan_unsorted(input, &block) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/langscan/elisp.rb', line 39 def scan_unsorted(input, &block) pm = LangScan::PairMatcher.new(2,2,2,2) pm.define_intertoken_fragment :space, nil pm.define_intertoken_fragment :comment, nil pm.define_pair :paren, :punct, "(", :punct, ")" reporter = lambda {|f| if (f.type == :ident || f.type == :funcall) && KeywordsHash[f.text] f.type = :keyword end if f.type == :quote_chars f.type = :punct end yield f } pm.parse(LangScan::EmacsLisp::Tokenizer.new(input), reporter) {|list| if (list.around_open(1).text == "defun" || list.around_open(1).text == "defmacro") && list.around_open(2).type == :ident list.around_open(2).type = :fundef end if list.around_open(1).type == :ident && funcall_list?(list) list.around_open(1).type = :funcall end } end |