FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
Eloquent-JavaScript/renderer/Highlight.hs at master · aeminem/Eloquent-JavaScript · GitHub
aeminem
/
Eloquent-JavaScript
Public
forked from
marijnh/Eloquent-JavaScript-1st-edition
Notifications
You must be signed in to change notification settings
Fork
0
Star
1
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
Eloquent-JavaScript
/
renderer
/
Highlight.hs
Copy path
More file actions
More file actions
Latest commit
History
History
History
326 lines (277 loc) · 12.6 KB
Breadcrumbs
Eloquent-JavaScript
/
renderer
/
Highlight.hs
Copy path
File metadata and controls
326 lines (277 loc) · 12.6 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
module
Highlight
(
highlightStatements
,
highlightExpression
)
where
import
Html
import
Text.ParserCombinators.Parsec
import
Data.Char
import
Data.Map
hiding
(
map
,
null
)
import
Data.Set
hiding
(
map
,
null
)
--
Parser
data
WordType
=
LikeIf
|
LikeDo
|
LikeNew
|
Function
|
Var
|
Catch
|
For
|
Case
|
Operator
|
Atom
|
Variable
deriving
(
Show
,
Eq
)
wordTypes
::
Map
String
WordType
wordTypes
=
Data.Map.
fromList([(
"
if
"
,
LikeIf
), (
"
switch
"
,
LikeIf
), (
"
while
"
,
LikeIf
), (
"
with
"
,
LikeIf
),
(
"
else
"
,
LikeDo
), (
"
do
"
,
LikeDo
), (
"
try
"
,
LikeDo
), (
"
finally
"
,
LikeDo
),
(
"
return
"
,
LikeNew
), (
"
break
"
,
LikeNew
), (
"
continue
"
,
LikeNew
),
(
"
new
"
,
LikeNew
), (
"
delete
"
,
LikeNew
), (
"
throw
"
,
LikeNew
),
(
"
in
"
,
Operator
), (
"
typeof
"
,
Operator
), (
"
instanceof
"
,
Operator
),
(
"
var
"
,
Var
), (
"
for
"
,
For
), (
"
case
"
,
Case
), (
"
function
"
,
Function
), (
"
catch
"
,
Catch
),
(
"
true
"
,
Atom
), (
"
false
"
,
Atom
), (
"
undefined
"
,
Atom
), (
"
null
"
,
Atom
),
(
"
NaN
"
,
Atom
), (
"
Infinity
"
,
Atom
)]);
wordType
::
String
->
WordType
wordType word
=
findWithDefault
Variable
word wordTypes
data
PState
=
PS
[[
String
]] [(
String
,
String
)]
output
::
String
->
String
->
CharParser
PState
()
output text style
=
updateState write
where
write (
PS
env out)
=
PS
env ((text, style)
:
out)
getOutput
::
CharParser
PState
[(
String
,
String
)]
getOutput
=
do
(
PS
_ ps)
<-
getState
return
ps
pushContext
::
CharParser
PState
()
pushContext
=
updateState push
where
push (
PS
env out)
=
PS
([
"
arguments
"
,
"
this
"
]
:
env) out
popContext
::
CharParser
PState
()
popContext
=
updateState pop
where
pop (
PS
(e
:
es) out)
=
PS
es out
registerVariable
::
String
->
CharParser
PState
Bool
registerVariable name
=
do
PS
env out
<-
getState
if
(
null
env)
then
return
False
else
do
setState (
PS
(update env) out)
return
True
where
update (e
:
es)
=
((name
:
e)
:
es)
isLocalVariable
::
String
->
CharParser
PState
Bool
isLocalVariable name
=
do
PS
env _
<-
getState
return
((
any
(
elem
name)) env)
punctuation
::
Char
->
CharParser
PState
()
punctuation c
=
do
char c
output [c]
"
punctuation
"
ws
commaSep
::
CharParser
PState
a
->
CharParser
PState
[
a
]
commaSep p
=
sepBy p (punctuation
'
,
'
)
zeroOrOne
::
CharParser
st
t
->
CharParser
st
[
t
]
zeroOrOne p
=
do
one
<-
p
return
[one]
<|>
return
[]
symbolOperator
::
CharParser
st
[
Char
]
symbolOperator
=
many1 (oneOf
"
+-*&%/=<>!|
"
)
wordOperator
::
CharParser
st
[
Char
]
wordOperator
=
do
name
<-
word
if
(wordType name
/=
Operator
)
then
unexpected name
else
return
name
operator
::
CharParser
PState
()
operator
=
do
op
<-
(symbolOperator
<|>
wordOperator)
output op
"
operator
"
ws
keyword
::
String
->
CharParser
PState
()
keyword name
=
do
string name
output name
"
keyword
"
ws
untilUnescaped
::
Char
->
CharParser
st
[
Char
]
untilUnescaped c
=
do
next
<-
anyChar
if
(next
==
c)
then
return
[next]
else
if
(next
==
'
\\
'
)
then
do
next'
<-
anyChar
rest
<-
untilUnescaped c
return
(next
:
next'
:
rest)
else
do
rest
<-
untilUnescaped c
return
(next
:
rest)
regexp
,
stringValue
,
numberValue
,
hexNumberValue
,
ws
::
CharParser
PState
()
regexp
=
do
char
'
/
'
content
<-
untilUnescaped
'
/
'
options
<-
many (oneOf
"
ig
"
)
output (
'
/
'
:
(content
++
options))
"
string
"
ws
stringValue
=
do
delimiter
<-
(char
'
"
'
<|>
char
'
\'
'
)
content
<-
untilUnescaped delimiter
output (delimiter
:
content)
"
string
"
ws
numberValue
=
do
digits
<-
many1 digit
dot
<-
((try afterDot)
<|>
return
"
"
)
exp
<-
(
exponent
<|>
return
"
"
)
output (digits
++
dot
++
exp
)
"
atom
"
ws
where
afterDot
=
do
char
'
.
'
digits
<-
many1 digit
return
(
'
.
'
:
digits)
exponent
=
do
exp
<-
oneOf
"
eE
"
minus
<-
zeroOrOne (char
'
-
'
)
digits
<-
many digit
return
(
exp
:
(minus
++
digits))
hexNumberValue
=
do
x
<-
try (
do
char
'
0
'
oneOf
"
xX
"
)
digits
<-
many1 (satisfy isHexDigit)
output (
'
0
'
:
x
:
digits)
"
atom
"
ws
ws
=
spaces
<|>
(try lineComment)
<|>
(try comment)
<|>
return
()
where
spaces
=
do
space
<-
many1 (satisfy isSpace)
output space
"
whitespace
"
ws
lineComment
=
do
string
"
//
"
content
<-
many (satisfy (
/=
'
\n
'
))
output (
"
//
"
++
content)
"
comment
"
ws
comment
=
do
string
"
/*
"
content
<-
manyTill anyChar (try (string
"
*/
"
))
output (
"
/*
"
++
content
++
"
*/
"
)
"
comment
"
ws
word
::
CharParser
st
[
Char
]
word
=
do
start
<-
satisfy varStart
rest
<-
many (satisfy varLetter)
return
(start
:
rest)
where
varStart c
=
isAlpha c
||
c
==
'
_
'
||
c
==
'
$
'
varLetter c
=
varStart c
||
isDigit c
statement
::
CharParser
PState
()
statement
=
(punctuation
'
;
'
)
<|>
block
<|>
wordStatement
<|>
exprStatement
where
block
=
do
punctuation
'
{
'
many statement
punctuation
'
}
'
exprStatement
=
do
expression
punctuation
'
;
'
wordStatement
,
wordExpression
::
CharParser
PState
()
wordStatement
=
do
start
<-
word
perform start (action start)
where
perform start (
Just
act)
=
do
output start
"
keyword
"
ws
act
perform start
Nothing
=
(try (label start))
<|>
(expr start)
label start
=
do
output start
"
property
"
ws
punctuation
'
:
'
expr start
=
do
wordExpression' start
punctuation
'
;
'
action word
=
case
(wordType word)
of
LikeIf
->
Just
(
do
punctuation
'
(
'
expression
punctuation
'
)
'
statement)
LikeDo
->
Just
statement
Function
->
Just
functionDef
Var
->
Just
(
do
commaSep variableDef
punctuation
'
;
'
)
Catch
->
Just
(
do
pushContext
punctuation
'
(
'
newVariable
punctuation
'
)
'
statement
popContext)
For
->
Just
(
do
punctuation
'
(
'
(try forIn)
<|>
normalFor
punctuation
'
)
'
statement)
Case
->
Just
(
do
expression
punctuation
'
:
'
statement)
otherwise
->
Nothing
forIn
=
do
optional (keyword
"
var
"
)
newVariable
keyword
"
in
"
expression
normalFor
=
do
statement
optional expression
punctuation
'
;
'
optional expression
wordExpression
=
do
start
<-
word
wordExpression' start
wordExpression'
::
String
->
CharParser
PState
()
wordExpression' start
=
case
(wordType start)
of
LikeNew
->
do
name
"
keyword
"
optional expression
Operator
->
do
name
"
operator
"
expression
Function
->
do
name
"
keyword
"
functionDef
Atom
->
do
name
"
atom
"
maybeOperator
Variable
->
do
local
<-
isLocalVariable start
name (
case
local
of
{
True
->
"
localvariable
"
;
False
->
"
variable
"
})
maybeOperator
where
name n
=
do
output start n
ws
newVariable, variableDef, functionDef, propertyName, objectLiteral, arrayLiteral,
expression
,
postFixOperator
,
maybeOperator
::
CharParser
PState
()
newVariable
=
do
name
<-
word
local
<-
registerVariable name
output name (
case
local
of
{
True
->
"
variabledef
"
;
False
->
"
variable
"
})
ws
variableDef
=
do
newVariable
optional assignment
where
assignment
=
do
punctuation
'
=
'
expression
functionDef
=
do
optional newVariable
pushContext
punctuation
'
(
'
commaSep newVariable
punctuation
'
)
'
statement
popContext
propertyName
=
do
name
<-
word
output name
"
property
"
ws
objectLiteral
=
do
punctuation
'
{
'
commaSep property
punctuation
'
}
'
where
property
=
do
(stringValue
<|>
numberValue
<|>
hexNumberValue
<|>
propertyName)
punctuation
'
:
'
expression
arrayLiteral
=
do
punctuation
'
[
'
commaSep expression
punctuation
'
]
'
expression
=
do
(parenthesed
<|>
regexp
<|>
stringValue
<|>
hexNumberValue
<|>
numberValue
<|>
objectLiteral
<|>
arrayLiteral
<|>
wordExpression)
maybeOperator
<|>
do
operator
expression
where
parenthesed
=
do
punctuation
'
(
'
expression
punctuation
'
)
'
postFixOperator
=
do
op
<-
(string
"
++
"
)
<|>
(string
"
--
"
)
output op
"
operator
"
ws
maybeOperator
=
funCall
<|>
propValue
<|>
propSubscript
<|>
(try postFixOperator)
<|>
choiceOperator
<|>
operator'
<|>
return
()
where
operator'
=
do
operator
expression
choiceOperator
=
do
punctuation
'
?
'
expression
punctuation
'
:
'
expression
funCall
=
do
punctuation
'
(
'
commaSep expression
punctuation
'
)
'
maybeOperator
propValue
=
do
punctuation
'
.
'
propertyName
maybeOperator
propSubscript
=
do
punctuation
'
[
'
expression
punctuation
'
]
'
maybeOperator
--
Html generation
significantStyles
::
Set
String
significantStyles
=
Data.Set.
fromList [
"
keyword
"
,
"
atom
"
,
"
variable
"
,
"
string
"
,
"
variabledef
"
,
"
localvariable
"
,
"
property
"
,
"
comment
"
];
simplifyOutput
::
[(
String
,
String
)]
->
[(
String
,
String
)]
simplifyOutput output
=
simplify (
map
removeStyle output)
where
removeStyle (value, style)
|
Data.Set.
member style significantStyles
=
(value, style)
|
otherwise
=
(value,
"
"
)
simplify
[]
=
[]
simplify [o]
=
[o]
simplify ((v1, s1)
:
rest)
=
let
a
@
((v2, s2)
:
rest')
=
simplify rest
in
if
(s2
==
s1)
then
((v1
++
v2, s1)
:
rest')
else
((v1, s1)
:
a)
toHtml
::
(
String
,
String
)
->
HTML
toHtml (value,
"
"
)
=
Tx
value
toHtml (value, style)
=
Tg
"
span
"
[(
"
class
"
, style)] [
Tx
value]
highlightOutput
::
[(
String
,
String
)]
->
[
HTML
]
highlightOutput
=
(
map
toHtml)
.
simplifyOutput
.
reverse
highlightStatements
,
highlightExpression
::
String
->
[
HTML
]
highlightStatements
=
highlight (
do
{ws; many statement; eof; getOutput})
highlightExpression
=
highlight (
do
{ws; expression; eof; getOutput})
highlight
::
CharParser
PState
[(
String
,
String
)]
->
String
->
[
HTML
]
highlight parser code
=
case
runParser parser (
PS
[]
[]
)
"
"
code
of
Right
ps
->
highlightOutput ps
Left
err
->
error
(
"
In code:
\n\n
"
++
code
++
"
\n\n
Parse error at
"
++
(
show
err))
Back
|
FazBrowse Home
|
New Git URL