# SPDX-License-Identifier: BSD-2-Clause function awkescape(string) { gsub(/\\/, "\\\\", string) gsub(/"/, "\\\"", string) return string } function awkrepr(v) { if(v == _nil()) return "_nil()" else if(v == _true()) return "_true()" else if(v == _false()) return "_false()" else if(v+0 == v) return v else { awkescape(v) return "\"" v "\"" } } function _dump(filename, i, t, v, s, line) { logg_dbg("_dump", "dumping to " filename) print "BEGIN {" >filename print " N = " N " # next cell number" >>filename print " N_at_last_gc = " N_at_last_gc >> filename for(i in _TYPE) { # i is not a number but a string. somewhere in the code we # ask if _TYPE[something] == bla, where something may be # true, or false, or nil, or a literal number ("# 123"); # and by asking about _TYPE[something], we make # _TYPE[something] exist, and be "". we don't want to dump # those here because _TYPE[# 123] is not valid awk syntax. if((i+0)!=i) continue t = _TYPE[i] line = " _TYPE[" i "] = \"" t "\"; " if(t == "'") { v = _SYM_NUMBERS[i] awkescape(v) line = line \ "_SYM_NUMBERS[" i "] = \"" v "\"; " \ "_SYM_NAMES[\"" v "\"] = " i "; " } else if(t == "s") { v = _STRING[i] awkescape(v) line = line "_STRING[" i "] = \"" v "\"; " } else if(t == "(") { line = line \ "_CAR[" i "] = " awkrepr(_CAR[i]) "; " \ "_CDR[" i "] = " awkrepr(_CDR[i]) "; " } print line >>filename } print " _GLOBALS = " _GLOBALS " # global environment " >>filename print " _MACROS = " _MACROS >>filename print " _COMPARED_SYMBOLS = " _COMPARED_SYMBOLS >>filename print "}" >>filename close(filename) return _true() } function dotescape(string) { gsub(/\\/, "\\\\", string) gsub(/"/, "\\\"", string) return string } function dotrepr(v) { if(v == _nil()) return _nil() else if(v == _true()) return _true() else if(v == _false()) return _false() else if(v+0 == v) return v else { dotescape(v) return v } } function _dump_dot(filename, i, t, v, s, n, node, edge, edge2) { logg_dbg("_dump_dot", "dumping Graphviz to " filename) print "digraph g {" >filename print " rankdir=LR" >>filename print " overlap=false" >>filename print " node [style=filled]" >>filename for(i in _TYPE) { # i is not a number but a string. somewhere in the code we # ask if _TYPE[something] == bla, where something may be # true, or false, or nil, or a literal number ("# 123"); # and by asking about _TYPE[something], we make # _TYPE[something] exist, and be "". we don't want to dump # those here. if((i+0)!=i) continue t = _TYPE[i] print "/* " i " is a " _TYPE[i] " : " _repr(i) " */" >>filename if(t == "(") { print "/* -- " _CAR[i] " is a " _TYPE[_CAR[i]] " : " _repr(_CAR[i]) " */" >>filename t = _TYPE[_CAR[i]] node = " n" i " [shape=record,label=\"{<n> " i "|" edge = "" edge2 = "" if(t == "(") { node = node "<car> ·|" edge = " n" i ":car -> n" _CAR[i] ":n;" } else if(t == "'") { v = _SYM_NUMBERS[_CAR[i]] dotescape(v) node = node v "|" #edge =" n" i ":car -> n" _CAR[i] " [constraint=false];" } else if(t == "s") { v = _STRING[_CAR[i]] dotescape(v) node = node "\\\"" v "\\\"|" } else { node = node dotrepr(_CAR[i]) "|" } if(_is_null(_CDR[i])) { node = node "<cdr> X}\"];" } else { node = node "<cdr> ·}\"];" edge2 = " n" i ":cdr -> n" _CDR[i] ":n [color=blue];" } print node >>filename print edge >>filename print edge2 >>filename } else if(t == "'") { print " n" i " [shape=Mrecord,label=\"{<n> " i "|" _SYM_NUMBERS[i] "}\"];" >>filename } else if(t == "s") { print " n" i " [shape=record,label=\"{<n> " i "|" _STRING[i] "}\"];" >>filename } } print " nGlobals [label=\"_GLOBALS\"];" >>filename print " nGlobals -> n" _GLOBALS ";" >>filename print " nMacros [label=\"_MACROS\"];" >>filename print " nMacros -> n" _MACROS ";" >>filename print " nCompared [label=\"_COMPARED_SYMBOLS\"];" >>filename print " nCompared -> n" _COMPARED_SYMBOLS ";" >>filename print "/*sweep colors*/" >>filename print "/*mark colors*/" >>filename print "}" >>filename close(filename) logg_dbg("_dump_dot", "done") return _true() }