Skip to content
This repository was archived by the owner on Jun 4, 2019. It is now read-only.

Commit e0fb08f

Browse files
committed
lang_lisp: simple lexer-based highlighter
1 parent 4eba308 commit e0fb08f

9 files changed

Lines changed: 253 additions & 8 deletions

File tree

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
(* Yoann Padioleau
2+
*
3+
* Copyright (C) 2010 Facebook
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public License
7+
* version 2.1 as published by the Free Software Foundation, with the
8+
* special exception on linking described in file license.txt.
9+
*
10+
* This library is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
13+
* license.txt for more details.
14+
*)
15+
16+
open Common
17+
18+
open Ast_lisp
19+
20+
module Ast = Ast_lisp
21+
module PI = Parse_info
22+
23+
open Highlight_code
24+
25+
module T = Parser_lisp
26+
27+
(*****************************************************************************)
28+
(* Prelude *)
29+
(*****************************************************************************)
30+
31+
(*****************************************************************************)
32+
(* Helpers when have global analysis information *)
33+
(*****************************************************************************)
34+
35+
let fake_no_def2 = NoUse
36+
let fake_no_use2 = (NoInfoPlace, UniqueDef, MultiUse)
37+
38+
(*****************************************************************************)
39+
(* Code highlighter *)
40+
(*****************************************************************************)
41+
42+
let visit_toplevel ~tag_hook prefs (toplevel, toks) =
43+
44+
let already_tagged = Hashtbl.create 101 in
45+
let tag = (fun ii categ ->
46+
tag_hook ii categ;
47+
Hashtbl.add already_tagged ii true
48+
)
49+
in
50+
51+
(* -------------------------------------------------------------------- *)
52+
(* ast phase 1 *)
53+
(* -------------------------------------------------------------------- *)
54+
55+
(* -------------------------------------------------------------------- *)
56+
(* toks phase 1 *)
57+
(* -------------------------------------------------------------------- *)
58+
59+
(*
60+
* note: all TCommentSpace are filtered in xs so easier to write
61+
* rules (but regular comments are kept as well as newlines).
62+
*)
63+
64+
let rec aux_toks xs =
65+
match xs with
66+
| [] -> ()
67+
68+
(* a little bit pad specific *)
69+
| T.TComment(ii)
70+
::T.TCommentNewline (ii2)
71+
::T.TComment(ii3)
72+
::T.TCommentNewline (ii4)
73+
::T.TComment(ii5)
74+
::xs ->
75+
76+
let s = PI.str_of_info ii in
77+
let s5 = PI.str_of_info ii5 in
78+
(match () with
79+
| _ when s =~ ".*\\*\\*\\*\\*" && s5 =~ ".*\\*\\*\\*\\*" ->
80+
tag ii CommentEstet;
81+
tag ii5 CommentEstet;
82+
tag ii3 CommentSection1
83+
| _ when s =~ ".*------" && s5 =~ ".*------" ->
84+
tag ii CommentEstet;
85+
tag ii5 CommentEstet;
86+
tag ii3 CommentSection2
87+
| _ when s =~ ".*####" && s5 =~ ".*####" ->
88+
tag ii CommentEstet;
89+
tag ii5 CommentEstet;
90+
tag ii3 CommentSection0
91+
| _ ->
92+
()
93+
);
94+
aux_toks (T.TComment ii3::T.TCommentNewline ii4::T.TComment ii5::xs)
95+
96+
97+
| x::xs ->
98+
aux_toks xs
99+
in
100+
let toks' = toks +> Common.exclude (function
101+
| T.TCommentSpace _ -> true
102+
| _ -> false
103+
)
104+
in
105+
aux_toks toks';
106+
107+
(* -------------------------------------------------------------------- *)
108+
(* toks phase 2 *)
109+
110+
toks +> List.iter (fun tok ->
111+
match tok with
112+
| T.TComment ii ->
113+
if not (Hashtbl.mem already_tagged ii)
114+
then
115+
(* a little bit syncweb specific *)
116+
let s = PI.str_of_info ii in
117+
if s =~ "(\\*[sex]:" (* yep, s e x are the syncweb markers *)
118+
then tag ii CommentSyncweb
119+
else tag ii Comment
120+
121+
| T.TCommentNewline ii | T.TCommentSpace ii
122+
-> ()
123+
124+
| T.TUnknown ii
125+
-> tag ii Error
126+
| T.EOF ii
127+
-> ()
128+
129+
| T.TString (s,ii) ->
130+
tag ii String
131+
132+
| T.TNumber (s,ii) ->
133+
tag ii Number
134+
135+
| T.TIdent (s, ii) ->
136+
(match s with
137+
| "defun"
138+
-> tag ii Keyword
139+
| "setq"
140+
-> tag ii KeywordObject (* hmm not really *)
141+
142+
| "t" ->
143+
tag ii Boolean
144+
| "nil" ->
145+
tag ii Boolean (* or Null ? *)
146+
147+
| "cond" | "if" ->
148+
tag ii KeywordConditional
149+
150+
| "concat"
151+
| "getenv"
152+
-> tag ii Builtin
153+
154+
| _ -> ()
155+
)
156+
157+
158+
| T.TCBracket ii
159+
| T.TOBracket ii
160+
-> tag ii TypeVoid (* TODO *)
161+
162+
| T.TCParen ii
163+
| T.TOParen ii
164+
-> tag ii Punctuation
165+
166+
| T.TQuote ii ->
167+
tag ii EmbededHtml (* quote stuff is kind of like XHP after all *)
168+
169+
| T.TAt ii
170+
| T.TComma ii
171+
| T.TBackQuote ii
172+
->
173+
tag ii EmbededHtml (* quote stuff is kind of like XHP after all *)
174+
175+
176+
177+
);
178+
179+
(* -------------------------------------------------------------------- *)
180+
(* ast phase 2 *)
181+
182+
()
183+
184+
185+
186+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
val visit_toplevel :
3+
tag_hook:
4+
(Ast_lisp.info -> Highlight_code.category -> unit) ->
5+
Highlight_code.highlighter_preferences ->
6+
Ast_lisp.toplevel * Parser_lisp.token list ->
7+
unit

lang_lisp/parsing/parser_lisp.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
open Common
1717

18+
module PI = Parse_info
19+
1820
(*****************************************************************************)
1921
(* Types *)
2022
(*****************************************************************************)
@@ -88,3 +90,5 @@ let info_of_tok tok =
8890
visitor_info_of_tok (fun ii -> res := Some ii; ii) tok +> ignore;
8991
Common.some !res
9092

93+
94+
let str_of_tok x = PI.str_of_info (info_of_tok x)

lang_ml/analyze/highlight_ml.ml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,8 @@ let disable_token_phase2 = false
7171
* number and basic entities. The Ast is better for tagging idents
7272
* to figure out what kind of ident it is.
7373
*)
74+
let visit_toplevel ~tag_hook prefs (*db_opt *) (toplevel, toks) =
7475

75-
let visit_toplevel
76-
~tag_hook
77-
prefs
78-
(*db_opt *)
79-
(toplevel, toks)
80-
=
8176
let already_tagged = Hashtbl.create 101 in
8277
let tag = (fun ii categ ->
8378
tag_hook ii categ;

tests/lisp/foo.lisp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
(setq debug-on-error t) ;or --debug-init
66

77
(defun h(s) (concat (getenv "HOME") "/" s))
8+
9+
(setq bar 1001)

visual/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ INCLUDEDIRS=$(TOP)/commons $(TOP)/globals \
3838
$(TOP)/lang_ml/analyze \
3939
$(TOP)/lang_nw/parsing \
4040
$(TOP)/lang_nw/analyze \
41+
$(TOP)/lang_lisp/parsing \
42+
$(TOP)/lang_lisp/analyze \
4143
$(TOP)/lang_cpp/parsing \
4244
$(TOP)/lang_cpp/analyze \
4345
$(TOP)/lang_js/parsing \

visual/draw2.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ let draw_content2 ~cr ~layout ~context ~nblines ~file rect =
381381
| FT.PL (FT.Cplusplus | FT.C)
382382
| FT.PL (FT.Thrift)
383383
| FT.Text ("nw" | "tex" | "texi" | "web")
384+
| FT.PL (FT.Lisp _)
384385
) ->
385386

386387
let column = ref 0 in

visual/parsing2.ml

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ open Highlight_code
3535
*)
3636
type ast =
3737
| ML of Parse_ml.program2
38+
3839
| Php of Parse_php.program2
39-
| Cpp of Parse_cpp.program2
4040
| Js of Parse_js.program2
4141

42+
| Cpp of Parse_cpp.program2
43+
44+
| Lisp of Parse_lisp.program2
4245
| Noweb of Parse_nw.program2
4346

4447

@@ -60,6 +63,14 @@ let parse_nw_cache a =
6063
match parse_nw2 a with | Noweb a -> a | _ -> raise Impossible
6164
)
6265

66+
let parse_lisp2 file =
67+
Common.memoized _hmemo_file file (fun () ->
68+
Lisp (Parse_lisp.parse file +> fst))
69+
let parse_lisp_cache a =
70+
Common.profile_code "View.parse_lisp_cache" (fun () ->
71+
match parse_lisp2 a with | Lisp a -> a | _ -> raise Impossible
72+
)
73+
6374

6475
let parse_php2 file =
6576
Common.memoized _hmemo_file file (fun () ->
@@ -244,6 +255,40 @@ let tokens_with_categ_of_file file hentities =
244255
)
245256
) +> List.flatten
246257

258+
| FT.PL (FT.Lisp _) ->
259+
let h = Hashtbl.create 101 in
260+
261+
let ast2 = parse_lisp_cache file in
262+
ast2 +> List.map (fun (ast, (_str, toks)) ->
263+
(* computing the token attributes *)
264+
Highlight_lisp.visit_toplevel
265+
~tag_hook:(fun info categ -> Hashtbl.add h info categ)
266+
prefs
267+
(ast, toks)
268+
;
269+
270+
(* getting the text *)
271+
toks |> Common.map_filter (fun tok ->
272+
let info = Parser_lisp.info_of_tok tok in
273+
let s = Parser_lisp.str_of_tok tok in
274+
275+
if not (Parse_info.is_origintok info)
276+
then None
277+
else
278+
let categ = Common.hfind_option info h in
279+
let categ = categ +> Common.fmap (fun categ ->
280+
rewrite_categ_using_entities s categ file hentities
281+
)
282+
in
283+
Some (s, categ,
284+
{ l = Parse_info.line_of_info info;
285+
c = Parse_info.col_of_info info;
286+
})
287+
288+
)
289+
) +> List.flatten
290+
291+
247292
| FT.Text ("nw" | "tex" | "texi" | "web") ->
248293

249294
let h = Hashtbl.create 101 in

visual/parsing2.mli

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ val use_arity_of_use_count : int -> Highlight_code.use_arity
99

1010
type ast =
1111
| ML of Parse_ml.program2
12+
1213
| Php of Parse_php.program2
13-
| Cpp of Parse_cpp.program2
1414
| Js of Parse_js.program2
1515

16+
| Cpp of Parse_cpp.program2
17+
18+
| Lisp of Parse_lisp.program2
1619
| Noweb of Parse_nw.program2
1720

1821
val _hmemo_file : (Common.filename, ast) Hashtbl.t

0 commit comments

Comments
 (0)