In case anyone is interested, I came up with this simple code to generate the call graph: import org.nlogo.headless.HeadlessWorkspace import org.nlogo.nvm._
case class GraphEdge(from : String, to: String, isolate : Boolean) { override def toString = s"$from -> $to" def toCSV = s"$from,$to,$isolate" } object GraphEdge { def apply(from: String, to: String) : GraphEdge = { val isolate = to match { case "" => true case _ => false } apply(from, to, isolate) } } object GenerateCallGraph { def extractCallGraph(procedures : Procedure.ProceduresMap) : Set[GraphEdge] = { val procNames = procedures.keySet println("printing the procNames") procNames foreach println println("*******printing the calls") val edges = procedures.map{case(parent,child) => { println(s"working procedure: $parent") val (gcall,gargs) = child.code.partition(_.toString.contains("_call")) val topEdges = gcall.map(c => GraphEdge(from=parent,to=c.displayName)) // greports : Array[Array[org.nlogo.nvm.Reporter]] val greports = gargs.map(_.args).filter(a => a.exists(_.toString.contains("_callreport"))) val argEdges = greports.map(r => { val edge = GraphEdge(from=parent, to=r(0).displayName) println(s"making edge in proc: $parent => $edge") edge }) argEdges match { case e if e.isEmpty => topEdges.toList case _ => topEdges.toList ::: argEdges.toList } }} val edgeSet = edges.toList.flatten.toSet edgeSet foreach println edgeSet } def run(modelFileName : String, callGraphOutFileName : String) : Unit = { val workspace = HeadlessWorkspace.newInstance workspace.open(modelFileName) val procs = workspace.procedures val callGraph = extractCallGraph(procs) val output = callGraph.map(_.toCSV).toList Utils.writeFile(callGraphOutFileName, output) workspace.dispose() } } On Thursday, June 11, 2020 at 11:41:03 AM UTC-4, Steve Upton wrote: > > Shoot, has it been that long?? > > Your answers, and references, are enough to get me going. I'll parse the > Commands since I don't see where to get the FrontEndResults - maybe they > have been discarded. Or maybe someone else will pipe in. > > thanx again > steve > > On Thursday, June 11, 2020 at 11:20:30 AM UTC-4, Seth Tisue wrote: >> >> It's now been more than five years since I worked on NetLogo; there's a >> limit to how much I still remember. >> >> In particular, I don't remember whether it's possible to get back to the >> ASTs after the entire compiler has run, or whether they have already been >> discarded and it's too late. >> >> I found some prior discussions in this area in the NetLogo room on Gitter: >> >> * https://gitter.im/NetLogo/NetLogo?at=5be1a45dda57ff676c9d4305 — "you >> want `FrontEndResults` and not `CompilerResults`. "FrontEndResults contains >> ProcedureDefinition objects, these have the ASTs inside them. see >> AstNode.scala" >> * https://gitter.im/NetLogo/NetLogo?at=5bba30ccc7bf7c3662cda279 >> >> But anyway, although my first thought was to walk the ASTs, on second >> thought it might be easier and just as effective for your use case to walk >> the fully compiled model (the `Array[Command]` inside each procedure) and >> look for the `_call` and `_callreport` nodes there. Any `_call`s will be in >> the `Array[Command]` directly, but to find the `_callreport`s you'll need >> recursively walk the `args` tree under each `Command`. >> >> Seth >> > -- You received this message because you are subscribed to the Google Groups "netlogo-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to netlogo-devel+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/netlogo-devel/af675a50-601e-4a20-8d54-4deb5338c211o%40googlegroups.com.