\ Copyright 2007,2009 - J.L. Bezemer
\ Converts GCC generated .s files to Graphviz DOT sourcefiles
\ http://www.graphviz.org
\ -- INPUT FORMAT --
\ o Plain text files
\ -- INPUT FORMAT --
\ -- TYPICAL USE --
\ $ gcc -S hello.c
\ $ 4th cxq asm2dot.4th hello.s hello.dot
\ -- TYPICAL USE --
false constant ignorecase \ C is case sensitive
false constant MINGW \ use Linux syntax by default
include lib/row.4th
include lib/2rotover.4th
9 constant tab \ TAB character
256 constant #node \ max. number of nodes
33 constant /node \ size per nodes
512 constant #edge \ max. number of edges
/node 3 [*] constant /edge \ size per edge
/node string this-node \ current node buffer
/edge string this-edge \ current edge buffer
#node /node [*] string nodes \ array for nodes
#edge /edge [*] string edges \ array for edges
variable top-node \ top of node buffer
variable top-edge \ top of edge buffer
s| "| sconstant quote \ a double quote
\ general definitions
: >edge /edge * edges + ; ( n -- a)
: colon? this-node count dup 0> ; ( -- a n f)
\ is edge unique?
: unique? ( -- f)
true top-edge @ 0 ?do \ loop till top of edge array
drop this-edge count i >edge count compare
dup 0= if leave then \ if not unique return false
loop
;
\ edge definitions
: +edge! this-edge count 2dup top-edge @ >edge place 1 top-edge +! type cr ;
: edge! 0 this-edge c! ; ( --)
: +edge this-edge +place ; ( a n --)
: "> quote +edge ; ( --)
: ;> s" ;" +edge ; ( --)
: node> "> MINGW [IF] chop [THEN] +edge "> ;
: +edge? edge! node> s" -> " +edge node> ;> unique? if +edge! then ;
\ node definitions
: >node /node * nodes + ; ( n -- a)
: node@ >node count ; ( n1 -- a n2)
: +node! 2dup top-node @ >node place 1 top-node +! ;
MINGW [IF]
: colon! [char] ; parse-word +node! this-node place ;
: label? over c@ [char] _ = ; ( a n -- a n f)
[THEN]
MINGW [NOT] [IF]
: colon! [char] , parse-word +node! this-node place ;
true constant label? ( -- f)
[THEN]
: defined?
top-node @
0 ?do 2dup i node@ compare 0= if 2over 2over 2swap +edge? leave then loop
;
\ is this a node?
: node? 2swap label? if defined? then ;
: edge-detect tab parse-word colon? if node? then 2drop 2drop ;
( --)
create parsing \ keywords and actions
," call" ' edge-detect ,
MINGW [IF] ," .def" ' colon! , [THEN]
MINGW [NOT] [IF] ," .type" ' colon! , [THEN]
NULL ,
:this parsing does>
2 string-key row if nip nip cell+ @c execute else drop 2drop then ;
: PreProcess
0 dup dup top-node ! top-edge ! this-node c!
." digraph asm {" cr
." node [color=lightblue2, style=filled];" cr
." ratio=1.0;" cr
;
\ required by 'convert.4th'
: Read-file refill ;
: PostProcess [char] } emit cr ;
: Usage abort" Usage: asm2dot asm-source dot-source" ;
: Process tab parse-word parsing ;
include lib/convert.4th
|