@@ -8,33 +8,107 @@ const Cthulhu = Base.PkgId(UUID("f68482b8-f384-11e8-15f7-abe071a5a75f"), "Cthulh
8
8
# syntax highlighting
9
9
#
10
10
11
- const _pygmentize = Ref {Union{String,Nothing}} ()
12
- function pygmentize ()
13
- if ! isassigned (_pygmentize)
14
- _pygmentize[] = Sys. which (" pygmentize" )
15
- end
16
- return _pygmentize[]
17
- end
11
+ # https://github.com/JuliaLang/julia/blob/dacd16f068fb27719b31effbe8929952ee2d5b32/stdlib/InteractiveUtils/src/codeview.jl
12
+ const hlscheme = Dict {Symbol, Tuple{Bool, Union{Symbol, Int}}} (
13
+ :default => (false , :normal ), # e.g. comma, equal sign, unknown token
14
+ :comment => (false , :light_black ),
15
+ :label => (false , :light_red ),
16
+ :instruction => ( true , :light_cyan ),
17
+ :type => (false , :cyan ),
18
+ :number => (false , :yellow ),
19
+ :bracket => (false , :yellow ),
20
+ :variable => (false , :normal ), # e.g. variable, register
21
+ :keyword => (false , :light_magenta ),
22
+ :funcname => (false , :light_yellow ),
23
+ )
18
24
19
25
function highlight (io:: IO , code, lexer)
20
- highlighter = pygmentize ()
21
- have_color = get (io, :color , false )
22
- if highlighter === nothing || ! have_color
26
+ if ! haskey (io, :color )
23
27
print (io, code)
28
+ elseif lexer == " llvm"
29
+ InteractiveUtils. print_llvm (io, code)
30
+ elseif lexer == " ptx"
31
+ highlight_ptx (io, code)
24
32
else
25
- custom_lexer = joinpath (dirname (@__DIR__ ), " res" , " pygments" , " $lexer .py" )
26
- if isfile (custom_lexer)
27
- lexer = ` $custom_lexer -x`
28
- end
29
-
30
- pipe = open (` $highlighter -f terminal -P bg=dark -l $lexer ` , " r+" )
31
- print (pipe, code)
32
- close (pipe. in)
33
- print (io, read (pipe, String))
33
+ print (io, code)
34
34
end
35
- return
36
35
end
37
36
37
+ const ptx_instructions = [
38
+ " abs" , " cvt" , " min" , " shfl" , " vadd" , " activemask" , " cvta" , " mma" , " shl" , " vadd2" ,
39
+ " add" , " discard" , " mov" , " shr" , " vadd4" , " addc" , " div" , " mul" , " sin" , " vavrg2" ,
40
+ " alloca" , " dp2a" , " mul24" , " slct" , " vavrg4" , " and" , " dp4a" , " nanosleep" , " sqrt" ,
41
+ " vmad" , " applypriority" , " ex2" , " neg" , " st" , " vmax" , " atom" , " exit" , " not" ,
42
+ " stackrestore" , " vmax2" , " bar" , " fence" , " or" , " stacksave" , " vmax4" , " barrier" ,
43
+ " fma" , " pmevent" , " sub" , " vmin" , " bfe" , " fns" , " popc" , " subc" , " vmin2" , " bfi" ,
44
+ " isspacep" , " prefetch" , " suld" , " vmin4" , " bfind" , " istypep" , " prefetchu" , " suq" ,
45
+ " vote" , " bmsk" , " ld" , " prmt" , " sured" , " vset" , " bra" , " ldmatrix" , " rcp" , " sust" ,
46
+ " vset2" , " brev" , " ldu" , " red" , " szext" , " vset4" , " brkpt" , " lg2" , " redux" , " tanh" ,
47
+ " vshl" , " brx" , " lop3" , " rem" , " testp" , " vshr" , " call" , " mad" , " ret" , " tex" , " vsub" ,
48
+ " clz" , " mad24" , " rsqrt" , " tld4" , " vsub2" , " cnot" , " madc" , " sad" , " trap" , " vsub4" ,
49
+ " copysign" , " match" , " selp" , " txq" , " wmma" , " cos" , " max" , " set" , " vabsdiff" , " xor" ,
50
+ " cp" , " mbarrier" , " setp" , " vabsdiff2" , " createpolicy" , " membar" , " shf" , " vabsdiff4" ]
51
+
52
+ # simple regex-based highlighter
53
+ # https://docs.nvidia.com/cuda/parallel-thread-execution/index.html
54
+ function highlight_ptx (io:: IO , code)
55
+ function get_token (s)
56
+ # TODO : doesn't handle `ret;`, `{1`, etc; not properly tokenizing symbols
57
+ m = match (r" (\s *)([^\s ]+)(.*)" , s)
58
+ m != = nothing && (return m. captures[1 : 3 ])
59
+ return nothing , nothing , nothing
60
+ end
61
+ print_tok (token, type) = Base. printstyled (io,
62
+ token,
63
+ bold = hlscheme[type][1 ],
64
+ color = hlscheme[type][2 ])
65
+ buf = IOBuffer (code)
66
+ while ! eof (buf)
67
+ line = readline (buf)
68
+ indent, tok, line = get_token (line)
69
+ istok (regex) = match (regex, tok) != = nothing
70
+ isinstr () = first (split (tok, ' .' )) in ptx_instructions
71
+ while (tok != = nothing )
72
+ print (io, indent)
73
+
74
+ # comments
75
+ if istok (r" ^\/\/ " )
76
+ print_tok (tok, :comment )
77
+ print_tok (line, :comment )
78
+ break
79
+ # labels
80
+ elseif istok (r" ^[\w ]+:" )
81
+ print_tok (tok, :label )
82
+ # instructions
83
+ elseif isinstr ()
84
+ print_tok (tok, :instruction )
85
+ # directives
86
+ elseif istok (r" ^\. [\w ]+" )
87
+ print_tok (tok, :type )
88
+ # guard predicates
89
+ elseif istok (r" ^@!?%p.+" )
90
+ print_tok (tok, :keyword )
91
+ # registers
92
+ elseif istok (r" ^%[\w ]+" )
93
+ print_tok (tok, :variable )
94
+ # constants
95
+ elseif istok (r" ^0[xX][A-F]+U?" ) || # hexadecimal
96
+ istok (r" ^0[0-8]+U?" ) || # octal
97
+ istok (r" ^0[bB][01]+U?" ) || # binary
98
+ istok (r" ^[0-9]+U?" ) || # decimal
99
+ istok (r" ^0[fF]{hexdigit}{8}" ) || # single-precision floating point
100
+ istok (r" ^0[dD]{hexdigit}{16}" ) # double-precision floating point
101
+ print_tok (tok, :number )
102
+ # TODO : function names
103
+ # TODO : labels as RHS
104
+ else
105
+ print_tok (tok, :default )
106
+ end
107
+ indent, tok, line = get_token (line)
108
+ end
109
+ print (io, ' \n ' )
110
+ end
111
+ end
38
112
39
113
#
40
114
# code_* replacements
0 commit comments